Blog Archives

Exceptions (part 3, advanced)

For Windows Forms and WPF we have specific exceptions to deal with. Actually these are not really exceptions. They are events, which are raised whenever any unhandled exception occurs. “Unhandled” means there is nothing that catches exceptions and the entire stack did not come up with any solution. Nothing stopped the thread falling down to its lowest level, and even that level does not know what to do with the exception. You can eg. throw an exception on a button click to cause this behavior.
These events allow applications to log information about unhandled exceptions.

In Windows Forms the EventHandler is defined in System.Threading and is called ThreadExceptionEventHandler. If you do not define this event call then your application will crash when unhandled exceptions show up.

[STAThread]
static void Main() {
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.ThreadException += Application_ThreadException;
    Application.Run(new Form1());
} //

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) {
    Exception lException = (Exception)e.Exception;
    MessageBox.Show(lException.Message);
} //

The approach in WPF is similar. We are talking in Domains. Therefore we subscribe to AppDomain.CurrentDomain.UnhandledException .

public MainWindow() {
    InitializeComponent();
    AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;            
} //

void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
    Exception lException = (Exception)e.ExceptionObject;
    MessageBox.Show(lException.Message + "\nIsTerminating: " + e.IsTerminating);
} //

private void button1_Click(object sender, RoutedEventArgs e) {
    throw new Exception("user exception thrown");
} //
Advertisements

Exceptions (part 2, advanced)

Season’s Greetings!
Today we have a very short post about custom exceptions, which provide more specific information. Of course the custom exception has to inherit from System.Exception. Adding several constructors including a parameterless one is good practice.
The suffix “Exception” in your exception name is convention (eg. “OutOfMemory
Exception
“, “FileNotFoundException“). Adding the Serializable attribute can be useful when you work across application domains. Properties help providing extra information.

Don’t use the System.ApplicationException class.
http://msdn.microsoft.com/en-us/library/system.applicationexception.aspx states:

If you are designing an application that needs to create its own exceptions, you should derive custom exceptions from the Exception class. It was originally thought that custom exceptions should derive from the ApplicationException class; however in practice this has not been found to add significant value.

In other words: ApplicationException is a relic of the past, where Microsoft intended developers to inherit all their custom exceptions from. But this has never become practice and custom exceptions now derive from the Exception class.

[Serializable]
public class UserNotFoundException : Exception {
    public string UserId { get; private set; }
            
    public UserNotFoundException(string xUserId) : base() {
        UserId = xUserId;
        base.HelpLink = "http://www.ohta.de";
    } // constructor

    public UserNotFoundException(string xUserId, string xMessage)
        : base(xMessage) {
        UserId = xUserId;
        base.HelpLink = "http://www.ohta.de";
    } // constructor

    public UserNotFoundException(string xUserId, string xMessage, Exception xInnerException)
        : base(xMessage, xInnerException) {
        UserId = xUserId;
        base.HelpLink = "http://www.ohta.de";
    } // constructor

    protected UserNotFoundException(SerializationInfo xSerializationInfo, StreamingContext xStreamingContext) {
        UserId = xSerializationInfo.GetValue("UserId", typeof(string)) as string;
    } // constructor

    public void GetObjectData(SerializationInfo xSerializationInfo, StreamingContext xStreamingContext) {
        xSerializationInfo.AddValue("UserId", UserId, typeof(string));
    }
} // class