views:

251

answers:

8

hi,

i know this could be a little weird but a doubt is a doubt afterall... what would happen in the following situation...

private void SendMail()
{
    try
    {
        //i try to send a mail and it throws an exception
    }
    catch(Exception ex)
    {
        //so i will handle that exception over here
        //and since an exception occurred while sending a mail
        //i will log an event with the eventlog

        //All i want to know is what if an exception occurs here
        //while writing the error log, how should i handle it??
    }
}

Thank you.

+4  A: 

I would personally wrap the call to write to event log with another try\catch statement.

However, ultimately it depends on what your specification is. If it is critical to the system that the failure is written to the event log then you should allow it to be thrown. However, based on your example, I doubt this is what you want to do.

David Relihan
+1. Btw: "yo dog, I heard you like catching Exceptions so I put a try-catch in your try-catch so you catch while you catch." :)
ANeves
Haha Brilliant!!!!!!! Comment of the week as far as I'm concerned!!!!
David Relihan
hey David,Even i believe you are correct, we should let the 2nd exception to be thrown because ultimately if an exception is thrown over there then that would mean that the problem exists with the client machine....and our first preference is exceptions related to our application...but then how do i find out what error occurred in my application because neither a mail was sent and neither was the error logged ???any suggestions buddy
Shrewd Demon
Well if it causes a run time exception you could examine the dump with some tool like Dr Watson - again I would try to avoid that. For the embedded try\catch I would write to write to a file as a last hope. That way you of 3 levels of notification with Mail at top, event log next and then log file - but let the call to log file throw if it fails.
David Relihan
A: 

You could add a try-catch block in your catch block as well.

thelost
+1  A: 

Each exception is caught only when inside a try-catch block. You could nest try-catch but is generally not a good idea.

VoodooChild
Right, nesting try-catch blocks feels "dirty". However, there is not much else one can do.
Dercsár
A: 

Considering the kind of exceptions when writing to a file (rights, disk space...) I would advice not to handle it in here. If it fails the first time, there's good chance you won't be able to write to the event log that it's not possible to write in the event log...

Let it bubble up and be handled by an upper level try/catch.

Sylvestre Equy
+2  A: 

You can simply catch errors in the error logging method. However I wouldn't personally do that, as broken error logging is a sign your application can't function at all.

private void SendMail()
{
    try
    {
        //i try to send a mail and it throws an exception
    }
    catch(Exception ex)
    {
        WriteToLog();
    }
}

private void WriteToLog()
{
    try
    {
        // Write to the Log
    }
    catch(Exception ex)
    {
        // Error Will Robinson
        // You should probably make this error catching specialized instead of pokeman error handling
    }
}
Chris S
+1 Yep - writeToLog should handle its own exceptions (either suppress or throw)
David Relihan
A: 

Chris S. has the best answer. Placing a try-catch block inside a catch block is very rarely a good idea. and in your case it will just convolute your code. If you check to see if you were successful in writing to your log file here, you will have to do it in every place where you try to write into your log file. You can easily avoid this unnecessary code duplication by having all your individual modules be self contained when it comes to notifying/handling of error conditions within these modules. When sending your mail fails you perform the proper actions inside your catch block to handle this exceptional condition like:

  1. disposing of the contents of your mail object
  2. making sure your socket is closed
  3. writing an entry into your log file to note the error

Inside your catch block just call whatever API you have defined to writing a log entry into your logfile and forget about about the rest. Inside your logging API is where you should handle any logging related exceptional cases (the disk is full, no permission to write to file, file not found, etc...). Your mailing module does not need to know if the logging was successful or not, that responsibility should be delegated to the logging module.

Peter
A: 

I personally handle this situation using a simple extension method.

public static class MyExtentions
{
    public static void LogToErrorFile(this Exception exception)
    {
        try
        {
            System.IO.File.AppendAllText(System.IO.Path.Combine(Application.StartupPath, "error_log.txt"),
                String.Format("{0}\tProgram Error: {1}\n", DateTime.Now, exception.ToString()));
        }
        catch 
        { 
            // Handle however you wish
        }
    }
}

The usage is simple:

try
{
   ...
}
catch(Exception ex)
{
   ex.LogToErrorFile();
}

You can then handle the caught exception inside the extension method however you want, or simply don't catch it and let it bubble up to the top. I've found this design to be a simple, reproducible way to handle exceptions throughout the application.

drharris
A: 
  • Firstly I would say don't catch "Exception" in catch block. You could instead, for mailing, check for all validity and then catch specific exception(SmtpException, ) that you can do something about(and informing user with a friendly message). Throwing exception from your code and informing the UI about is not a bad idea. If your methods accepts inputs with certain specification and if they are not met, your method should/can throw error and inform user about it.

  • For exceptions that have no control over, use global handling exception, like Application_Error for web. Getting Better Information on Unhandled Exceptions Peter Bromberg explains this better.

  • Also for any privildged resource you are accessing, like eventlogs, make sure you assembly has access to it.

  • Useful links Build a Really Useful ASP.NET Exception Engine By Peter A. Bromberg and Documenting Exceptional Developers By Peter A. Bromberg For web application look into Health monitoring Exception logging

  • One more thing, if your application goes wrong/ throws error that can't handle( at all) its better to let it go down gracefully and not continue. Application in unstable state is not good idea.

PRR