How to escape from a nested Catch statement - c#

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"
}

Related

How to programmatically retrieve reason code from a XMS XMSException

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;
}
}

Send exception to Caller method in c#

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;
}

What problems do you see with passing exception handling to a single method?

I'm currently working with some code that is used in client server communication.
I has a lot (around 50) of the following try-catch blocks
try
{
return GetLogFiles(date);
}
catch (TimeoutException ex)
{
this.GetLogger("GetAllLogs").Error("C is not answering!", ex);
}
catch (ConnectionInterruptedException ex)
{
this.GetLogger("GetAllLogs").Error("Connection interrupted", ex);
}
catch (ActionNotSupportedException ex)
{
this.GetLogger().Error("Software-version not comaptible!", ex);
throw new VersionNotCompatibleException();
}
catch (EndpointNotFoundException ex)
{
this.GetLogger().Error("Problem with network, connection to core is lost!", ex);
}
catch (CommunicationException ex)
{
this.GetLogger().Error("Not expected communication-exception was thrown:", ex);
}
This makes for a LOT of code that is more or less always the same.
Now I thought about refactoring all the catch blocks into a method and just call it. Like
try
{
return GetLogFiles(date);
}
catch(Exception ex)
{
ExceptionHandling(string operation, Exception ex)
}
private void ExceptionHandling(string operation, Exception ex)
{
if (ex is TimeoutException)
{
this.GetLogger(operation).Error("C is not answering!", ex);
}
else if (ex is ConnectionInterruptedException)
{
this.GetLogger(operation).Error("Connection interrupted", ex);
}
else if (ex is CommunicationObjectFaultedException)
{
this.GetLogger(operation).Error("Core is not answering!", ex);
}
else if (ex is FaultException)
{
this.GetLogger(operation).Error("C is not answering!", ex);
}
else if (ex is ActionNotSupportedException)
{
this.GetLogger().Error("Software-version not comaptible!", ex);
throw new VersionNotCompatibleException();
}
else if (ex is EndpointNotFoundException)
{
this.GetLogger().Error("Problem with network, connection is lost!", ex);
}
else if (ex is CommunicationException)
{
this.GetLogger().Error("Not expected communication-exception was thrown:", ex);
}
else
{
this.GetLogger().Error("Unknown exception was thrown:", ex);
throw new Exception("Unknown exception occured during request handling", ex);
}
}
None of the codeparts does any ordinary handling in case of an exception, i.e. they get logged and that's it.
What problems do you see with extracting the exception part into its own method?
The main problem I see is that you're rethrowing the exception if it isn't one you expect, making you lose the real stack trace, plus using Exception in your catch is a very broad thing to do.
Lines of code isn't the real issue, and yes making things DRY is a good thing to do but its more likely that the thing that needs making dry is the GetLogFiles function to include the error handling inside of that, not the exception handler.
it's better to do that like this:
public class MyException : Exception
{
public MyException(Exception ex)
{
// handle exception
}
}
and
try
{
}
catch(Exception ex)
{
throw new MyException(ex)
}

Try inside catch to ensure finally executes

I have to process items off a queue.
Deleting items off the queue is a manual call to Queue.DeleteMessage. This needs to occurs regardless of whether or not the processing succeeds.
var queueMessage = Queue.GetMessage();
try
{
pipeline.Process(queueMessage);
}
catch (Exception ex)
{
try
{
Logger.LogException(ex);
}
catch { }
}
finally
{
Queue.DeleteMessage(queueMessage);
}
Problem:
On failure, I log the error to some data store. If this logging fails (perhaps the data store is not available), I still need the message to be deleted from the queue.
I have wrapped the LogException call in another try catch. Is this the correct way or performing thing?
Following code is enough. finally blocks execute even when exception is thrown in catch block.
var queueMessage = Queue.GetMessage();
try
{
pipeline.Process(queueMessage);
}
catch (Exception ex)
{
Logger.LogException(ex);
}
finally
{
Queue.DeleteMessage(queueMessage);//Will be executed for sure*
}
The finally block always executes, even if it throws an unhandled error (unless it end the app). So yes.

Handling Error "WebDev.WebServer.Exe has stopped working"

Is there a way to handle the error "WebDev.WebServer.Exe has stopped working" in ASP.NET and keep the page running or even the just the WebServer running? Or is this an impossible task and is essentially like asking how to save someone's life after they've died?
I have the error-causing code inside a try/catch block, but that doesn't make a difference. I've also tried registering a new UnhandledExceptionEventHandler, but that didn't work either. My code is below in case I'm doing something wrong.
Also to be clear, I'm not asking for help on how to prevent the error; I want to know if and when the error happens if there's anything I can do to handle it.
UPDATE 1: TestOcx is a VB6 OCX that passes a reference of a string to a DLL written in Clarion.
UPDATE 2: As per #JDennis's answer, I should clarify that the catch(Exception ex) block is not being entered either. If I removed the call to the OCX from the try\catch block it still won't reach the UnhandledException method. There are essentially two areas that don't ever get executed.
UPDATE 3: From #AndrewLewis, I tried to also add a regular catch block to catch any non-CLS compliant exceptions, and this did not work either. However, I later found that since .NET 2.0 on, all non-CLS exceptions are wrapped inside RuntimeWrappedException so a catch (Exception) will catch non-CLS compliant exceptions too. Check out this other question here for more info.
public bool TestMethod()
{
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
string input = "test";
string result = "";
try
{
TestOcx myCom = new TestOcx();
result = myCom.PassString(ref input); // <== MAJOR ERROR!
// do stuff with result...
return true;
}
catch (Exception ex)
{
log.Add("Exception: " + ex.Message); // THIS NEVER GETS CALLED
return false;
}
}
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// THIS NEVER GETS CALLED
try
{
Exception ex = (Exception)e.ExceptionObject;
log.Add("Exception: " + ex.Message);
}
catch (Exception exc)
{
log.Add("Fatal Non-UI Error: " + exc.Message);
}
}
You should try catching non-CLS compliant exceptions to make sure nothing is being thrown (keep in mind you don't want to do this in production, always be specific!):
try
{
TestOcx myCom = new TestOcx();
result = myCom.PassString(ref input); // <== MAJOR ERROR!
// do stuff with result...
return true;
}
catch (Exception ex)
{
log.Add("Exception: " + ex.Message); // THIS NEVER GETS CALLED
return false;
}
catch
{
//do something here
}
Your code reads //THIS NEVER GETS CALLED.
If you catch the exception it is no longer un-handled. this is why it doesn't fire an unhandledexception event.

Categories