Where should exceptions be caught and handled in a WPF application? - wpf

We have exception catching code in most of our event handlers etc, this leads to very complex logic, with flags that are set to say if there has been an exception so as not do the next step etc.
At first sight I would move all exception report/logging to the AppDomain.UnhandledException event, however from my experience with WinForms this will lead to a lot of exceptions being lost.
Also when there is an exception we have include details of the operation the user was trying to do in the log message.
So what are people experiences both bad and good at exception logging/reporting/recovering in WCF applications?
(I would love to say that we had something like the Model-View ViewModel (MVVM) pattern) in use, but we don’t and are a long way from being able to use any “clean” design like that)

Its not specific to WPF, but the best place to handle exceptions is to handle them at the point where user interaction with the form is converted into a logic process. This is either in the codebehind or in a controller method.
Only at this level do you know what the user is trying to do and what reasonable steps to take when an exceptional situation is encountered.
Of course, if you don't know what exceptions may be thrown don't try to handle them. And don't bother handling exceptions that you can't do anything about.

You should never have to use flags to say exceptions have been handled - that smells like bad design.
Exceptions fall into two categories:
expected (e.g. validation failed, data could not be put into database)
unexpected
your expected ones should be handled pretty quickly, and logged depending on the type of exception. For instance, if the user entered some data that was rejected by validation code in the business layer, i would catch the exception and notify the user, but not log it - because it was expected and i can deal with it. Others could be "expected", but you cannot deal with it - like a WCF call failed due to timeout or oversized data packet. This you should definately log - you may even be able to recover from it, so once again it should be caught and dealt with. Note the lack of flags - an exception is either dealt with, or it continues to bubble up. If you need to take an action you can do so, and then rethrow the exception to let it bubble up further - look, still no flags :)
Another approach i have taken in the past when throwing (custom) expected exceptions in an ASP.NET application is to mark it as being capable of being handled locally or not. This means that when the aspx caught the error (generic error handler in a base page that all apsx's inherited from), then it knew whether it should just show it locally within the page (after doing a text lookup in a resource file), or whether it should redirect to an error page. This approach was especially useful when doing a mixture of standard postbacks and ajax callbacks (may not be particularly useful to WPF apps though).
For major unexpected errors, you can catch those at the Application level, here is a previous SO post about it. Another two related posts that might be useful here, and here.
Another thing i should mention is to make sure your error logging is relatively bulletproof - there is nothing worse than your exception logging process throwing an exception, and losing all the valuable details of that tricky bug you are trying to track down for that irate user.

Related

How to detect and wrap "debugging resource strings are unavailable" w/o installing developer runtime?

I'm working on a Silverlight app that has an UnhandledException handler in the App class, which shows a message box containing the exception message. This is often fine for custom exceptions. However, it's not so good for built-in exceptions (e.g. NullReferenceException), because users don't have the developer runtime installed and therefore get a rather ugly "Debugging resource strings are unavailable" message.
My first thought (which I quickly dismissed) was to check the exception message for "debugging resource strings". I imagine if someone's running the app in, say, French, they'd get something like "les chaînes de ressources de débogage", so that wouldn't work.
Perhaps there's a way for a Silverlight app to detect whether it's running in the end-user runtime vs. the developer runtime? I've looked in the Application and Environment and Deployment classes, and haven't found anything.
I suppose this wouldn't be an issue if the application always threw custom exceptions anytime some sort of message needed to be shown to the user. Then I could easily hide the non-custom ones with a friendlier generic message. Is that the best/only option?
Just from an application design point of view, what user will know what to do with any kind of techy error message? "The value 'null' was found where an instance of an object was required." huh??
A simple "Something bad happened, if it continues, please contact support" should suffice. Just ensure that you log whatever bad happened somewhere, so that when you get the phone call/email, you can retrieve the issue in whatever techy details you require to solve the problem.

How to return warnings from server side to silverlight

We have a business case that need to return both validation errors and warings from server side and display on silverlight.
I see the silverlight is using System.ComponentModel.DataAnnotations.ValidationResult to process errors. It does not contain and fields for "warnings".
I am wondering if anybody has a good idea to handle this problem. Thanks.
I think ValidationResult is used by ValidationException which is thrown by the subclasses of ValidationAttribute. Normally this mecanism is used with blocking validation errors because throwing to exception stops execution of the code. If it happens in your service, the exception can be sent to the client and processessed, but this is not always a wanted scenario.
You could extend this model (those classes ValidationAttribute, its subclasses, ValidationException are not sealed) to add a warning flag but then you'd have to trap the exception to continue the processing and rethrow in case of a warning.
Another alternative is to add business logic validation errors and warnings to your response to the client. I like this approach because you can then include whatever info you want the way you want/need it.

On Silverlight initialization, what exception to throw?

What's the best exception to throw if a Silverlight app fails initialization or fails to load?
Or should I not throw an exception at all?
In my experience, load/initialization failure sometimes results in a managed exception, sometimes not. In some cases, the exception or failed condition may only be accessible at the client through javascript. In the event of an exception that comes from the entire app failing, there should be some indication to the user that the app failed completely.
You should consume and handle exceptions that are thrown from init/load failure. Explicit throwing of exceptions should be reserved for conditions where there is a violation of business logic, communcations failure, or other truly exceptional case.
I personally don't like the UI that IE shows when a Silverlight application throws an unhandled exception. It has a very small window that shows the exception text but the options present certainly aren't user friendly. I guess this is a matter of opinion, but my preference is to catch any exceptions during initialization and try to present the user with a meaningful description of what happened. Typically I store some settings in isolated storage, so one helpful message might describe how to clear the iso store for my app to eliminate some sort of configuration problem. As long as you can provide the user with some meaningful steps to fix the problem, or at least who to contact if they can't, I'd say it's better not to throw exceptions during initialization that would cause the app to fail to load.

Silverlight 2 Webservices

I'm developing a silverlight application that consumes a webservice. Calls to this webservice are made Asynchronously. But when an exception occurs during a procedure of the async call, I get an error on the completed event but i lost my original exceptions information. Independent of what the original exception was, I always get "The remote server returned an error: NotFound" back, with stack that points to "external" code.
Any advice?
When the service throws an exception it's translated to a 40(x) HTTP response that gets handled by the browser before the Silverlight plugin can handle it. To avoid this, wrap your WCF calls in a try/catch block and send exception data back to the client through an HTTP response that can be handled by Silverlight, such as 200. Here's a terrific implementation of this strategy on codeproject:
http://www.codeproject.com/KB/silverlight/SilverlightExceptions.aspx
This happens with any exception in your SL to WCF, sometimes you can find the innerexception with Fiddler2 in the transfered data or you might see the HTTP error code which can give you a hint , other times it's harder to find. This is my big request item for SL 4.0, better WCF debugging.
http://www.fiddler2.com
Follow James Cadd's advice above. Getting more informative error messages will certainly help and, unfortunately, you can't rely on the debugger to generate them for you.
Even if you're not a big fan of unit testing, this is a place where it's more than worthwhile. Constructing a set of tests that will purposefully send your webservice bad data and making sure that you get back informative errors will help set you up to figure out why it's not working with the Silverlight app. Writing these kinds of tests takes a different way of thinking, but it will give you a lot of confidence in your code if you know that you've tried to break the webservice in every possible way and it always gives you back something you can use to trace the problem.

If exception handling should be centralised is the design of WinForm components flawed?

Or any other design that has the gui widgets as being the first port of call where an unhandled exception will kill the app?
We all want one main: "catch all" for face saving purposes (although in most cases this shouldn't have a "continue" feature) but it is impossible to easily implement one with gui widgets that are the first port of call. Is this design flawed or am I missing a trick somewhere?
I ask this because I was reading an article by the designer of the language and he stated that Exception handling should be centralised and the first thing that popped into my head was the WinForm event mechanism where this becomes difficult.
Were the WinForm/GUI team listening to him, or was it possibly too late by then?
You can put a try/catch around Application.Run, and handle Application.ThreadException. In the handlers you can log the exception and exit.
Apart from the above, I usually put an exception handler around all calls to the Business Tier (and all access to external resources in the client tier, e.g. export to a file) which display an error but don't exit the application.
Are you aware of Application.ThreadException? I'm not saying it's necessarily the best answer around, but it's at least an answer...

Resources