views:

102

answers:

4

Hello,

Is there any way to catch all the excepions within an application at Main() with a single try-catch irrespective of threads and appdomains within the application??

In other words I just want to use one try-catch to log all the errors in my application instead of using multiple try catches in various places.

Would appreciate any ideas or code snippets...

Thanks

Edit: I'm using a Console application and Windows Service.

A: 

In your Program.cs one might think you could use the following

[STAThread]
static void Main()
{
    try
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new ContactRegistry()); // or whatever you app is called
    }
    catch (Exception e)
    {
        // your stacktrace code goes here
        Console.Write(e.StackTrace);
    }
}
BennySkogberg
I have tried this...but some exceptions are not caught :(
Josh
have fun with stracktraces/performance!
Andreas Niedermair
"This class is the base class for all exceptions. When an error occurs, either the system or the currently executing application reports it by throwing an exception containing information about the error. Once thrown, an exception is handled by the application or by the default exception handler." ref: http://msdn.microsoft.com/en-us/library/system.exception(VS.71).aspxIf all exceptions inherit from Exception Class, I can't see why this wouldn't work. Do you have an example?
BennySkogberg
Exceptions from other threads aren't magically caught and some special exceptions propagate even after being caught (ThreadAbortException)
VirtualBlackFox
+2  A: 

Is there any way to catch all the excepions within an application at Main() with a single try-catch irrespective of threads and appdomains within the application??

No, exceptions are per thread so unless you do something to marshal exceptions from other threads to your main thread there's no way to catch exceptions from other threads.

E.g. if you invoke a delegate asynchronously you need to call EndInvoke to get any exception back to the calling thread. If you just start a thread and don't do anything to handle or marshal the exception, the unhandled exception will cause the runtime to shutdown the application.

Brian Rasmussen
how to do that? I mean marshal exceptions? What is the solution?
Josh
@Josh: Take a look at BeginInvoke/EndInvoke on delegates. When you execute code through BeginInvoke it will catch any exception and then re-throw it on the thread that calls EndInvoke.
Brian Rasmussen
+3  A: 

Take a look at http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx and http://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception.aspx.

I think it fits you're needs

Neothor
Please keep in mind that the application is still closed. AppDomain.UnhandledException is useful for logging, but it doesn't act as a catch all handler.
Brian Rasmussen
A: 

I doubt whether it would be useful to have a common place to log errors.

What do you want to achieve by this - code reduction?

Image an Exception called InvalidFileFormatException that could occur in your application whenever you try to open a file whose format is not as expected. A global exception handler could log this. Your logfile would then read something like:

[Yesterday...] The file format is invalid: InvalidFileFormatException. StackTrace: ...

But what do you gain by this information? Okay, I admit that if there's only one call in your whole application that can lead to this Exception being thrown then everything is fine. But what if there are multiple calls to the same method or if other called methods throw the same exception?

You have to rely on the Exception's detailed message, but unfortunately if it comes to Exceptions thrown by the Runtime, you cannot influence the messages. Wouldn't it be nicer to have something like

string fileName = @"C:\Users\stackoverflow\Documents\file.frk";

try
{
  FreakingObject fo = freakingObjectConverter.ReadFromFile(fileName, FreakFormat.AutoDetect);
}
catch (InvalidFileFormatException iffe)
{
  MyLogger.LogError("File " + fileName + " had an invalid format:", iffe);
}

In the example you at least get the information about the malformatted file. You could easily create more complex examples (HttpRequest etc.) where you can add very useful information to your log if only you were aware of the context the Exception was thrown in.

Small hint on the try-catch around Application.Run(...): keep in mind that whenever you reach the catch block, your application will exit if you do not respawn the main form or do anything else.

Andreas