Let's build an error handling aspect: part 6

April 22, 2014 mgroves 3 comments
Tags: LetsBuildAnAspect PostSharp

In the last post in the series, I moved the error handling aspect into an opinionated one by using Exceptionless and handling certain types of exceptions (like SqlException and NotImplementedException).

In this post, I'm going to go even further down the opinionated road and talk about exception recovery.

My goal is for any exception to be caught and logged, and we're already there. In addition, I'd like the user not to see a yellow screen, so I'm generally not allowing the exception to bubble up, in lieu of a nice error message being put into ModelState (or some other error handling). However, this might not be enough. If the service method throwing an exception has a return value, then it's likely that another error will happen later in execution (maybe due to a null reference). For example:

If the method doesn't throw an exception, everything is fine. If it does throw an exception, there will a null reference when I attempt to use the Count property. What I would prefer is that an empty collection is returned. In fact, this fits with the recommendations from Framework Design Guidelines (page 256) to always return an empty collection (or array) instead of null. I've added a helper method to construct the return value in case this occurs.

What about if the service method is not returning a collection? And what if it's returning a value (like int or DateTime)? It's okay to return a null in the first case. In the second case, it might be okay to throw an exception. I have so few of these in the project I'm working on that I don't worry about it much, but for the sake of completeness, let's just make it return the default value.

I need to be very cautious about what I'm doing, and wrap everything in a try/catch so that I don't end up causing another unhandled exception in my exception handling code. It would be a good idea to create some unit tests to make sure everything is behaving as expected.

Okay, I think one or two more posts will wrap it up for this series. We need to discuss whether or not the exception message should be shown to a user (hopefully you're leaning towards "no").

  • This only works for ITerritoryService
  • Swallowing exceptions: we should at least be logging the exception, not just ignoring it.
  • If the method has a return type, then it's returning null. If it's meant to return a reference type, that's probably fine, but what if it's returning a value type?
  • What if it's returning a collection, and the UI assumes that it will get an empty collection instead of a null reference?
  • Do we really want to return the exception message to the user?
  • What if I forget to use ServiceBase as a base class on a new service?
  • Unit tests: how to test this aspect in isolation.

 

Comments

Avatar for Daniel Rosales

Posted by Daniel Rosales on April 23, 2014

Matt, great stuff, trying to get thru chapter 3 of your book. I love the book. And your post, will help me as I am trying to write a Vehicla Tracker Application in ASP.NET MVC, take a peek... http://www.yarakot.com/vehicletrackerapp

Avatar for Ross

Posted by Ross on April 23, 2014

This seems like a lot of over-architecting for a problem that could be solved by having your service return Enumerable.Empty() instead of null when it comes across an error.

Avatar for mgroves

Posted by mgroves on April 24, 2014

The aspect is catching and logging the error (see posts 1 through 5), so the aspect is where I have to have it return an empty collection. But, I wonder if using Enumerable.Empty() would work instead of Activator.CreateInstance.

Leave a Comment

*
*
Some HTML will be escaped, you can use StackOverflow-flavored Markdown
Matthew D. Groves

About the Author

Matthew D. Groves lives in Central Ohio. He works remotely, loves to code, and is a Microsoft MVP.

Latest Comments

Twitter