Is it possible to get error message in try catch on C# (or window service that was written with C#) like this:
string input = Console.ReadLine();
while (input!="q")
{
try
{
double result = 10 / int.Parse(input);
Console.WriteLine("Divinced by " + input + " And result is " + result);
}
catch (Exception)
{
Console.WriteLine("Error, Please try again");
}
finally
{
input = Console.ReadLine();
}
}
It was built to ".exe" program.
If I input character ("A","B","C") or zero, then the program will show message "Error, Please try again" so I need to know error message.
I don't want to edit code. I need a tools to detect all error in program.
Thank you for your helping.
You want the exception's Message property to be printed. Replace your catch block with this:
catch (Exception e)
{
Console.WriteLine("An exception occurred : " + e.Message);
}
Related
I have a XMS MQ Client app that is pulling off messages from a series of MQ endpoints. There are certain reason codes for which the process can continue, and for some that it should abort. For example a MQRC_Q_MGR_NOT_AVAILABLE 2059 for one endpoint shouldn't abort the whole process. Consequently I would like to check for this reason code.
cf = factoryFactory.CreateConnectionFactory();
foreach (Endpoint e in env.GetEndpoints())
{
Console.WriteLine("Consuming messages from endpoint {0}({1})", e.host, e.port);
// Set the properties
SetConnectionProperties(cf, e);
try
{
ReceiveMessagesFromEndpoint(cf);
}
catch (XMSException ex)
{
Console.WriteLine("XMSException caught: {0}", ex);
Console.WriteLine("Error Code: {0}", ex.ErrorCode);
Console.WriteLine("Error Message: {0}", ex.Message);
}
}
Problem is that the only attributes available on the XMSException to examine are ex.ErrorCode and ex.Message, which are respectively:
Error Code: CWSMQ0006
and
Error Message: CWSMQ0006E: An exception was received during the call to the method ConnectionFactory.CreateConnection: CompCode: 2, Reason: 2059.
I can see the Reason in the Message, but can't find a method or attribute to retrieve it.
There are probably 2 ways to do it
1) You can use the LinkedException
Something like the following
try
{
}
catch (XMSException e)
{
if(e.LinkedException!=null)
Console.WriteLine(e.LinkedException.Message);
else
Console.WriteLine(e);
}
2) Reference amqmdnet.dll as well to the project and use MQException.Something like
try
{
}
catch (XMSException e)
{
if(e.LinkedException!=null)
{
IBM.WMQ.MQException inner = (IBM.WMQ.MQException)e.LinkedException;
Console.WriteLine("Reason:"+ inner.ReasonCode);
}
else
Console.WriteLine(e);
}
Solution by OP
Based on accepted answer, a 'working' code is:
cf = factoryFactory.CreateConnectionFactory();
foreach (Endpoint e in env.GetEndpoints())
{
Console.WriteLine("Consuming messages from endpoint {0}({1})", e.host, e.port);
// Set the properties
SetConnectionProperties(cf, e);
try
{
ReceiveMessagesFromEndpoint(cf);
}
catch (XMSException ex)
{
Console.WriteLine("XMSException caught: {0}", ex);
Console.WriteLine("Error Code: {0}", ex.ErrorCode);
Console.WriteLine("Error Message: {0}", ex.Message);
if (ex.LinkedException != null &&
IBM.XMS.MQC.MQRC_Q_MGR_NOT_AVAILABLE.ToString().Equals(ex.LinkedException.Message))
{
Console.WriteLine("Queue Manager on this endpoint is not available");
Console.WriteLine("Moving onto next endpoint");
continue;
}
Console.WriteLine("Unexpected Error - Aborting");
throw;
}
}
Hello guys i'm working on Database assignment in this i have one windows form and one class that i use to connect database and to execute queries and non-queries.
Question: I m using Post-Message label which inform only when "Product added successfully".but when i send wrong-data which can occur exception in executeNonQuery() in database class and after catching this exception and showing Error in message box.Control goes back to caller and it prints lblPostMsg in both cases which is "Product has been added successfully".
I want that when exception occur in database class i can stop executing rest of the code or if there is way that exception in calling method can be caught by caller method.
below is Code of windows Form button
private void btnInsert_Click(object sender, EventArgs e)
{
con = new DbConnection();
con.SqlQuery("INSERT INTO products VALUES(#products_ID,#products_Name)");
con.cmd.Parameters.AddWithValue("#products_ID", txtProID.Text);
con.cmd.Parameters.AddWithValue("#products_Name", txtProName.Text);
try
{
con.ExecuteNonQueryF();
this.categoriesTableAdapter1.Fill(this.purchasemasterDS.categories);
SystemSounds.Beep.Play();
lblPostMsg.Show();
lblPostMsg.Text = "Product has been added successfully";
}
catch (Exception ex)
{
throw;
}
finally
{
con.CloseCon();
}
}
This code is from dbclass
public void ExecuteNonQueryF()
{
try
{
_con.Open();
cmd.ExecuteNonQuery();
}
catch (System.Exception ex)
{
MessageBox.Show("Exception " + ex);
}
you are catching, handling, and suppressing the Exception in ExecuteNonQueryF:
catch (System.Exception ex)
{
MessageBox.Show("Exception " + ex);
}
Though this handles the Exception by showing the message, it causes the code to continue executing; the Exception won't be raised to the caller.
If you add throw after your MessageBox.Show is executed, the Exception will be raised to the caller and execution stops.
catch (System.Exception ex)
{
MessageBox.Show("Exception " + ex);
throw;
}
Another option is to completely remove that try-catch in ExecuteNonQueryF - letting the caller (your button onclick method) handle the Exception.
you need to throw an explicit exception in ExecuteNonQuery's catch block like
throw new Exception(ex)
and then in calle's catch block you need to write "return" to return from function. This will stop furter execution of function.
If you want the Exception will be raised to the caller and execution stops, then you must use throw at the last line of your catch block.
catch (System.Exception ex)
{
/*
write your desire code. then throw
*/
throw;
}
I have a try\catch block that handles opening a connection and inserting data into a database.
catch (SqlException ex)
{
string sqlError = null;
for (int i = 0; i < ex.Errors.Count; i++)
{
sqlError += "Error Message " + ex.Errors[i].Message + "\n" + "Stored Procedure " + ex.Errors[i].Procedure + " \n " + "Line Number " + ex.Errors[i].LineNumber;
}
LogTools.WriteLog("Sql Server error " + sqlError);
Variables.InstallStatusDetail = "Database connection failed";
if (!sqlError.Contains("connection to SQL Server"))
{
if (Variables.WriteToDatabase)
{ HostedDataBase.InsertRunStatusIntoInstallStatus('E', sqlError, null); }
}
}
I want to log sqlexceptions to the database that wont interfere with connecting and logging to the database. The problem occurs when the database cannot be found, or a login does not have the proper permissions, etc. The exception is raised, and it tries to log to the database, so when it does that, it calls the function that writes to the database and tries to access once again, but once again the same exception is raised, resulting in a loop of failed attempts to write to the database (either because the DSN cannot be found, or the user does not have proper permissions).
How can I handle sql errors that would prevent me from being able to access and write to the database, and at the same time still be able to write sql errors that would not cause this loop?
I'm slightly confused by your question but I will attempt to answer it. You have to be careful with how you handle exceptions. If you are going to attempt to reconnect to the database even though an exception was raised the first time, you may want to have some conditions checking what sort of exception was raised. This way, you know to only attempt to re-connect if it was an exception which will not be repeated over and over.
IE.
catch (SqlException ex)
{
Error = ex.ToString()
WriteToLog(Error);
CheckError();
}
Void CheckError()
{
//conditions based on error output.
}
void WriteToLog(string Error)
{
// write your error output to log
}
You should put your logging in it's own try..catch block, like this:
catch (SqlException ex)
{
string sqlError = null;
for (int i = 0; i < ex.Errors.Count; i++)
{
sqlError += "Error Message " + ex.Errors[i].Message + "\n" + "Stored Procedure " + ex.Errors[i].Procedure + " \n " + "Line Number " + ex.Errors[i].LineNumber;
}
LogTools.WriteLog("Sql Server error " + sqlError);
Variables.InstallStatusDetail = "Database connection failed";
if (!sqlError.Contains("connection to SQL Server"))
{
if (Variables.WriteToDatabase)
{
try {
//I am assuming this is where you are trying to write the error back into the database
HostedDataBase.InsertRunStatusIntoInstallStatus('E', sqlError, null);
} catch {
//ignore errors here
}
}
}
}
Unfortunately if you are writing to the same database that you don't have access to, I'm afraid you cannot do that.
I'd suggest you to use something like Log4net which can have multiple appenders (eventlog, database, file, etc). Also, log4net operates something like a fire and forget. Even if log4net has any issues logging the errors, it won't throw exceptions.
In the following code I have a nested Try Catch. In the case where my nested catch fails I want to just to the parent catch statement and execute that code. How can i do this?
try
{
try
{ // build and send invoice lines
ReadInvLinesToArray(row["ID_INVOICE"].ToString());
}
catch (Exception e)
{
writeToEventLog(e.ToString(), true, false);
SendErrorEmail("Failed to send Invoice Lines to NAV. The following system error was generated: \n" + e.ToString());
}
// send invoice header if lines have been sent
bool result = navInvoices.SendInvoicesToNAV(navImportInvoices);
// update the retrieved records, marking QB Status as value N, passing in the sql dataset as a list
UpdateQBStatusInvoiceSent(ref idInvoicesSent);
}
catch (Exception e)
{
// remove Invoice from list to ensure its status is not updated.
idInvoicesSent.Remove(Convert.ToInt32(row["ID_INVOICE"]));
WriteToEventLog(e.ToString(), true, false);
SendErrorEmail("Failed to send Invoices to NAV. The following system error was generated: \n" + e.ToString());
}
You CAUGHT the exception with that "inner" catch, so the exception has been deal with it. If you want the "outer" catch to trigger as well, you'd have to RE-THROW the exception:
try {
try {
...
} catch (Exception e) {
... do stuff
throw e; // you need this
}
} catch (Exception e) {
... catch the re-thrown "e"
}
I am writing an application in which when something happened to the connection I want to pop up a messagebox and show the user the error...
for this purpose when the program throw an exception it will come to the catch block and in that I want to show the user the message here is the code :
catch (WebException ex)
{
if (!(ex.Message == "The operation has timed out."))
{
MessageBox.Show(ex.Message);
}
}
As it seems the program will come to this catch something like forever till the connection is become fixed so what should I do to update my message on just one messagebox at a time?
There is not much control over MessageBox when it's displayed. I would use another Form displayed in a modal mode. Before displaying, you can start a separate thread and put the logic to monitor the connection. When re-established, notify the message form and close it.
You can use something like:
public static class FailureMessagebox
{
private static bool _hasBeenSuccessful = true;
public static void ShowIfFailure(Action someAction)
{
try
{
someAction();
_hasBeenSuccessful = false;
}
catch (Exception err)
{
if (_hasBeenSuccessful)
MessageBox.Show(ex.Message);
_hasBeenSuccessful = false;
throw;
}
}
}
Sample usage:
try
{
WebResponse response;
FailureMessagebox.ShowIfFailure(() => response = webRequest.GetResponse());
}
catch (WebException err)
{
//handle the exception here.
}