ispiro
ispiro

Reputation: 27673

Best practices for throwing exceptions that are to be displayed to the user

Unexpected exceptions that should terminate execution of the program are simply thrown. They are caught by CurrentDomain_UnhandledException and taken care of there - logged if necessary, and a generic "This app is about to crash and you have nothing to do about it" message displayed to the user.

But what about those exceptions that only need to cancel an operation, while showing the user a more useful message? e.g. informing the user that a file can't be accessed because it's being used by another process. This exception might be deeply nested, and I wouldn't want to check for some flag at every method return. I'd rather have something like this: when the user initiates the most "external" method - say, a button click event handler, the code will include a try-catch block catching all DisplayToUserException's , and rethrow any other exceptions. So I'll have to create this custom exception class.

But before I go down that path, I'd like to know if that's the standard thing to do, or perhaps there's a better solution for this. Or perhaps a class already built for this. Hence this question.

Upvotes: 0

Views: 77

Answers (1)

John Saunders
John Saunders

Reputation: 161773

It's ok to put a try/catch block around your UI events:

public void Button1_Click(object sender, EventArgs e)
{
    try {
        // Do something interesting, like calling methods that throw (nested) exceptions
        // Maybe these methods do file I/O
    }
    // Though it's better to catch a more-specific exception or set of exceptions
    catch (IOException ex){ 
        MessageBox.Show(ex.ToString());
    }
}

This limits the effects of the exception to the UI operation (the button click, in this case).

A truly unhandled exception, one that you can't anticipate or do anything about, will still get handled by the AppDomain exception handler.

Note also that the Message property of an exception is meant for display to the user. It's ok to catch a "technical" exception, and rethrow as an exception with a user-friendly message. But be sure to include the original exception:

try {
    // Do something with the file name in the <c>path</c> variable
}
catch(IOException ex){
    throw new InvalidOperationException(
        String.Format("Can't perform that file I/O on {0}, sorry about that", path), ex);
}

Upvotes: 1

Related Questions