Is there any way to handle all Exceptions of the software?

Asked

Viewed 233 times

6

I’m creating a DLL for use in various projects of mine. I created a method that captures Source, Message and other variables that I defined, assembles an email and sends them to myself. (a kind of error log by email).

Is there any way to reference this method once in the code and it capture every time a Exception is launched even without Try... Catch?

  • I forgot to comment that the ultimate goal is not to treat Exception itself, I just want it to be sent to my email. Ultimate goal is to know the bugs that happen in it after I have released its first version.

  • You decide what to do when an untreated exception is detected, both responses quote this.

2 answers

7


You can add a Event Handler for event AppDomain.UnhandledException, this event will be triggered when an exception is not detected/handled.

It allows the application to record information about the exception before the standard system handler reports the exception for the user and terminate the application. If enough information about the state of implementation is available, other measures can be taken - how to save program data for later recovery.

Caution is advised, because program data may be corrupted when exceptions are not treated.

Example taken from from here in C#.

Add a line to the main method (by default in the file Program.Cs in a new Windows application):

namespace MyApp
{
  static class Program
  {
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
      AppDomain.CurrentDomain.UnhandledException +=  new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
      Application.EnableVisualStyles();
      Application.SetCompatibleTextRenderingDefault(false);
      Application.Run(new Form1());
    }
  }
}

On the line AppDomain.CurrentDomain... is referencing a function that does not yet exist, so we will create it:

static void CurrentDomain_UnhandledException (object sender, UnhandledExceptionEventArgs e)
{
  try
  {
    Exception ex = (Exception)e.ExceptionObject;    
    MessageBox.Show("Erro! Entre em contato com os desenvolvedores com a seguinte" 
          + " informação:\n\n" + ex.Message + ex.StackTrace, 
          "Fatal Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
  }
  finally
  {
    Application.Exit();
  }
}

Now your untreated exceptions are being shown in a nice dialog, you can do other things around here - like register the exception, or try to soften the crash hit, you cannot however keep the program running after a crash, there’s no way to take the exception at this point and let the program work.

In VB.NET should look similar to this:

Module MyApp   
   Sub Main()
      Dim currentDomain As AppDomain = AppDomain.CurrentDomain
      AddHandler currentDomain.UnhandledException, AddressOf MyHandler

      Throw New Exception("Foo")
   End Sub 

   Sub MyHandler(sender As Object, args As UnhandledExceptionEventArgs)
      Dim e As Exception = DirectCast(args.ExceptionObject, Exception)

      Console.WriteLine("Erro! Entre em contato com os desenvolvedores com a seguinte : " + e.Message)
      ' Fazer alguma coisa aqui com a exceção não tratada.
   End Sub     
End MyApp
  • 1

    I fell into the same mistake, the question is about Vb.net.

3

Yes, there is. First there are some things I want to tell you.

Save some exception (with the pardon of pun) very well justified there is only one place where you should capture the Exception. It is close to the closure of the application. Often in the Main() or some method called by it. It is there that you must capture all the exceptions thrown and that have not been captured before. That’s where you should do what you said. And almost always the application should break even, may be in a "cute" way but is the best to do when the problem can not be fixed. And programming errors cannot be fixed at runtime. The most you can do to not let break is to start again with a zero state. The application would not break but would start all over again as if it were the first execution. So it should be in the Main() or very close to him.

But if you really want to capture something that has not even been captured there is a way:

'isto possivelmente vai no Main
Dim currentDomain = AppDomain.CurrentDomain
currentDomain.UnhandledException += new unhandledExceptionEventHandler(MyHandler)

Shared Sub MyHandler(object sender, UnhandledExceptionEventArgs args) {
   Dim e =  DirectCast(args.ExceptionObject, Exception)
   Console.WriteLine("Erro: {0}", e.Message)
   'aqui você pode fazer o que quiser
End Sub

I put in the Github for future reference.

Documentation.

I advise avoiding this method, this may not do what you expect.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.