Another juicy tidbit from an internal Q&A session.
The question...
How can I throw an exception from within a modal form on mine inside AutoCAD, and catch it in the calling command? I have tried try/catch, but nothing seems to work.
Here's my command definition:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using System.Windows.Forms;
using MyApplication;
using acApp =
Autodesk.AutoCAD.ApplicationServices.Application;
namespace CatchMeIfYouCan
{
public class Commands
{
[CommandMethod("CATCH")]
static public void CatchDialogException()
{
try
{
MyForm form = new MyForm();
DialogResult res =
acApp.ShowModalDialog(form);
}
catch (System.Exception ex)
{
MessageBox.Show(
"Caught using catch: " +
ex.Message,
"Exception"
);
}
}
}
}
And here's the code that throws an exception from behind button inside my form:
using System;
using System.Windows.Forms;
namespace MyApplication
{
public partial class MyForm : Form
{
public MyForm()
{
InitializeComponent();
}
private void button1_Click(
object sender,
EventArgs e
)
{
throw new Exception(
"Something bad happened."
);
}
}
}
The answer, once again, came from our AutoCAD Engineering team, in this case from one of our API Test Engineers based in Singapore...
I was able to catch the exception using the ThreadExceptionEventHandler event. Here is your modified command:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using System.Windows.Forms;
using System.Threading;
using MyApplication;
using acApp =
Autodesk.AutoCAD.ApplicationServices.Application;
using sysApp =
System.Windows.Forms.Application;
namespace CatchMeIfYouCan
{
public class Commands
{
[CommandMethod("CATCH")]
static public void CatchDialogException()
{
try
{
sysApp.ThreadException +=
new ThreadExceptionEventHandler(
delegate(
object o,
ThreadExceptionEventArgs args
)
{
MessageBox.Show(
"Caught using event: " +
args.Exception.Message,
"Exception"
);
}
);
MyForm form = new MyForm();
DialogResult res =
acApp.ShowModalDialog(form);
}
catch (System.Exception ex)
{
MessageBox.Show(
"Caught using catch: " +
ex.Message,
"Exception"
);
}
}
}
}
I gave this a try, myself, and saw that when we click the button on the dialog shown by the CATCH command, our event handler picks up the exception and displays it via a MessageBox:
One thing to note: when running this from the debugger, Visual Studio will break, telling us that there's an exception that has gone unhandled:
This can be ignored - and probably disabled inside Visual Studio - but it could be annoying, if you use this technique throughout your code. Perhaps someone who's implemented this approach - or another that works for them - can add a comment on how they handle this scenario?