Search code examples
c#autocadautocad-plugin

How to catch unhandled exceptions thrown in AutoCAD.NET


In my Autocad.NET app I want to log all unhandled exceptions using log4net. AutoCAD itself shows an error dialog with a detailed message -> so there must be a way to register to a certain event.

I tried to register the AppDomain.CurrentDomain.UnhandledException event at app initialization:

AppDomain.CurrentDomain.UnhandledException += (s, e) =>
{
     System.Exception exception = (System.Exception)e.ExceptionObject;
     log.Error(String.Format("Unhandled Exception: {0}\n{1}", exception.Message, exception.StackTrace));
};

But this event is never fired.


Solution

  • In ObjectARX, there is a function called acedDisableDefaultARXExceptionHandler. You can try to P/Invoke it.

        // EntryPoint may vary across autocad versions
        [DllImport("acad.exe", EntryPoint = "?acedDisableDefaultARXExceptionHandler@@YAXH@Z")]
        public static extern void acedDisableDefaultARXExceptionHandler(int value);
    

    You can also try System.Windows.Forms.Application.ThreadException: http://through-the-interface.typepad.com/through_the_interface/2008/08/catching-except.html

    The simplest way to do this is to wrap all your code in a try/catch block. In AutoCAD, there is 2 ways to execute code :

    With a command

    To avoid duplicate code, declare an interface like this:

    public interface ICommand
    {
      void Execute();
    }
    

    Then use it for your command:

    public class MyCommand : ICommand
    {
      void Execute()
      {
        // Do your stuff here
      }
    }
    

    In the class where your commands are defined, use this generic method to execute :

    void ExecuteCommand<T>() where T : ICommand
    {
      try
      {
        var cmd = Activator.CreateInstance<T>();
        cmd.Execute();
      }
      catch (Exception ex)
      {
        Log(ex);
      }
    }
    

    Now your command looks like this:

    [CommandMethod("MYCMD", CommandFlags.Modal)]
    public void MyCommand()
    {
      ExecuteCommand<MyCommand>();
    }
    

    In an event handler

    In this case, as you need the event arguments, simply wrap your code in the try/catch directly.