0

What is the best practice for exception handling in WinForms or WPF. I haven't found a satisfying solution so far. Some people suggest to catch the unhandled exception event. But I don't think that this is a good solution.

The problem

I have a 3 layer application. The persistence layer, the business layer and the ui layer. Instead of catching exceptions in all three layers I think the correct place to catch the exceptions are in the ui layer. So the user will get an error message and maybe there is also a way the user can 'solve' the issue (wrong data input, etc).

So the question is, is the best/correct way to surround EVERY ui-eventhandler (click event, selection changed event, etc) with a try catch block? Like this:

private void button_MouseUp(object sender, MouseButtonEventArgs e)
{
   try
   {
      /// ...
   }
   catch (Exception ex)
   {
      // log exception
      // show error to user if necessary
   }
}

I know that catching all exceptions is bad. And of course you need to prevent exceptions by validating the user input data. But sometimes there will be bugs ;).

Imagine the following situation: The user makes some changes which aren't saved yet. Then he clicks a button and in the button handler is a bug. So wouldn't it be better to show a error message and let the user decide when he wants to quit the application, so that the user won't lose the unsaved data?

3
  • 'Every' is over the top and catching all types (Exception ex) is not recommended. Commented Jan 14, 2014 at 9:19
  • 1
    Best-practice is to prevent user-action when it'll result in an error: e.g.: When nothing is selected and the user clicks, you can handle the nullreference you might get or you can make sure the button is disabled until something is selected. This approach applies to a lot of the situations. Commented Jan 14, 2014 at 9:23
  • I know that catching all types of exception is not recommended. And yes, preventing errors is a good practice. But imagine a user made some changes which are not saved to the database yet. And then the user clicks a button. The button handler has a bug, so the application crashes. Wouldn't it be better to show a error message and let the user decide when to quit the application? With this approach the user would have the chance to save the changes. Commented Jan 14, 2014 at 9:27

1 Answer 1

4

So the question is, is the best/correct way to surround EVERY ui-eventhandler (click event, selection changed event, etc) with a try catch block?

No. The only thing you do is to repeat yourself (violation of DRY). If you in the future want to change how exceptions are logged you have to go through every method that has a try/catch block.

You can use the Application.ThreadException event to catch all unhandled exceptions (in the UI thread) to display an error dialog to the user and log the exception.

The best way is of course to make sure that the user have supplied correct information by validating it. By doing so all exceptions that occurs are truly exceptions and not something that you could have prevented.

Here are my golden rules:

  1. Always try to prevent exceptions by making sure that the supplied data is correct.
  2. Only catch exceptions that you can use to resolve the situation without user involvement.
  3. Use Application.ThreadException event for all other errors (and log them).

You can read my exceptions series if you want to: http://blog.gauffin.org/2013/04/what-is-exceptions/

Sign up to request clarification or add additional context in comments.

10 Comments

I've edited the question. What do you do when you want to give the user the chance to save the changes he made? The repeating thing is exactly why I struggle with the try catch block in every ui event. Instead of writing logger.log(...) in every catch block I've made a ExceptionUI control which logs/reports the exception and shows the message to the user.
@bakunin, first of all - save action should't be in view but in some accurate service or in repository. <br>Then its <code>Save</code> method could return result is operation succesfull or not.
@bakunin IIRC, If you use the ThreadException event to display a dialog the form won't be closed and the application will not crash. Hence the user can correct the supplied information and try again.
@michasm the save action is not in the view. the user makes some changes to multiple domain objects, without saving them immediately. The user decides when he wants to save. So before saving he also makes some changes to other domain objects. While doing this an exception appears (the reason is a bug or whatever). So I think, the user wants to have a chance to save the domain objects which got changed correctly, instead of losing ALL unsaved data.
@bakunin: I would never do a partial save. If the objects are independent of each other you should also treat them as such in the UI.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.