2

I am trying to figure out how to return exceptions and errors up to the controller level from my repository and be able to return custom errors to the client when they call my web service.

I have the following example from my BookRepository class:

public BookViewModel GetBookById(Guid id)
{
      var Book = _Books.Collection.Find(Query.EQ("_id", id)).Single();
      return Book;
}

obviously my function would be a little more complicated than this, but if i called this method on a id that did not exist i would get an exception. How can I have my exceptions and custom errors bubble up to my controller and then displayed nicely in the client response

John Saunders
  • 160,644
  • 26
  • 247
  • 397
anthonypliu
  • 12,179
  • 28
  • 92
  • 154
  • Exceptions already bubble up to your caller. What do you mean? – John Saunders Mar 05 '13 at 18:47
  • In terms of "displayed nicely in the client response", and WebApi best practice for error handling... take a look at the answer here: http://stackoverflow.com/questions/13951005/best-practice-ways-to-handle-errors-and-exception-in-web-api-controllers/13955683#13955683 (Be sure to follow the link to the article in the answer too). – Mark Jones Mar 05 '13 at 20:40

3 Answers3

3

Even a web service should follow the same patterns as any other code, with respect to exception handling. Those best practices include not using custom exceptions unless the caller is going to make a programmatic choice based on the exception type. So,

public BookViewModel GetBookById(Guid id)
{
    try
    {
      var Book = _Books.Collection.Find(Query.EQ("_id", id)).Single();
      return Book;
    }
    catch (SpecificExceptionType1 ex)
    {
        Log.Write(ex);
        throw new Exception("Some nicer message for the users to read", ex);
    }
    catch (SpecificExceptionType2 ex)
    {
        Log.Write(ex);
        throw new Exception("Some nicer message for the users to read", ex);
    }
    catch (Exception ex)
    {
        Log.Write(ex);
        throw;  // No new exception since we have no clue what went wrong
    }
}
John Saunders
  • 160,644
  • 26
  • 247
  • 397
1

what edmastermind29 mentioned is one common way to do it. i would usually the same way.

but sometimes developers like to catch the exception before the controller and return a result message based on enumerated value for example , so the controller would have no try catch blocks for that call, it will only need to check the status message.

you can use out parameter to check status and display messages for users accordingly.

this is how ASP.NET Membership provider is implemented. check the method create user in Membership provider for example:

http://msdn.microsoft.com/en-us/library/system.web.security.membershipprovider.createuser(v=vs.100).aspx

Saad Alothman
  • 353
  • 2
  • 10
0

Place a try-catch around methods, LINQ queries, etc. that may fail given a circumstance (null value, empty value, invalid value, etc.). From there, you can catch the exception, and throw a custom exception tailored to what you are looking for. See below.

public BookViewModel GetBookById(Guid id)
{
   try
   {
      var Book = _Books.Collection.Find(Query.EQ("_id", id)).Single();
      return Book;
   }
   catch (Exception e)
   {
      Log.Write(e)
      status = "Some Custom Message";
   }
   catch (DoesNotExistException dne)
   {
      Log.Write(dne)
      status = "Some Custom Message about DNE";
   }
}
  • thanks for the quick reply, In this case, what if theres multiple lines that can throw an exception and how do you handle that in the controller and return in cleanly to the client in a web api – anthonypliu Mar 05 '13 at 18:39
  • Say you have three instances where exceptions may occur. You can: 1) Try block all the logic in the method, and catch different exceptions (see edit). 2) If you want to specify which instance threw an error (given you are looking for the same error), then your `innerException` will provide different detail. This is up to you on how you want to handle this, but using a custom message would work best if you want to return cleanly to the client. –  Mar 05 '13 at 18:44
  • Ask yourself how much detail your client actually will use. If you're just displaying to a user, then "Can't get book" is all you really need to say. And a custom exception is not required unless the calling code is going to make programmatic choices based on the exception type. – John Saunders Mar 05 '13 at 18:48
  • I have edited the code slightly to present logging the innerException `e` and setting `"Some Custom Message"` as a string variable that can be used to display a clean error message to the user through postback or javascript. –  Mar 05 '13 at 18:49
  • @JohnSaunders I present such as an example, but I agree with your logic. If there are multiple lines that can throw an exception and all the user needs to know that they can't get a book, then "Can't get book" is adequate. –  Mar 05 '13 at 18:51