WebApi/MVC 4 Exceptions As Control Flow Anti-Pattern

Topics: Web Api
Feb 16, 2012 at 12:50 PM

I notice that throwing exceptions to short-circuit requests has persisted into the MVC 4 beta. This smacks of being a performance anti-pattern to me. What are the team's thoughts on this? Shouldn't one avoid throwing exceptions except in exceptional circumstances? I'm nervous that either:

(a) Ignorant developers will abuse this.

(b) It provides a potential denial-of-service attack vector through deliberate bad requests consuming more processor cycles that necessary.

Is this hyperbole or a real issue?

See here for a blog post with some general background: http://blogs.msdn.com/b/alikl/archive/2008/02/02/performance-sin-using-exceptions-to-control-flow.aspx and there are many other references to this concept on .NET and other platforms around the web.

Whirly

Feb 16, 2012 at 4:15 PM

Do you not throw an HttpErrorResponse? That's a little different than an exception. I know it's an exception, but it also has context contained in it, of which, you can make it a 200 instead of a 500. And have your error handler return a list of messages as a proper object, or something of that sort. (This is what I use it for, I return a JsonErrorResponse object when a "cancellation" error is thrown).

Feb 17, 2012 at 3:13 AM
Yes, you can throw HttpResponseException from pretty much anywhere and we'll pick it up and convert it into the appropriate response.

That said, I personally think that throwing HttpResponseException from a method which can return an HttpResponseMessage is indicative of a lazy/poor application design.
Feb 17, 2012 at 3:17 AM

If you think that it's not good design, how are you supposed to return a typed error response that is different than what you register your output to be?

public Foo Endpoint(int range)

{
    // An invalid response was received, what would you do other than throw?

Coordinator
Feb 17, 2012 at 5:44 AM

@digitalpacman

That is a valid usage for HttpResponseException. The one advantage is it immediately exits processing.

Feb 17, 2012 at 6:48 AM
Edited Feb 17, 2012 at 7:26 AM

ok cool, wanted to make sure what I was doing wasn't considered bad practice. thanks. sorry for the thread hijack

Feb 17, 2012 at 1:03 PM

@digitalpacman's previous post:

>>If you think that it's not good design, how are you supposed to return a typed error response that is different than what you register your output to be?

That's kind of my point. I would argue you want to be able to return expected failures without having to throw an exception to it. With the current implementation, the only way to do this is to have every response type carry the ability to report a failure condition. You could do this with a type hierarchy:

class ResponseBase

class ErrorResponse : ResponseBase

class SomeGoodResponse : ResponseBase

and return HttpResponseMessage<ResponseBase> from every method. But that's uuuuuuuuuuuuuugggggly!

Maybe HttpResponseMessage<TSuccess, TFail> would do it so you have a choice of setting two different Content properties, one for success, one for failure. I'm sure there's a better way than this... but I'm not sure throwing exceptions as control flow is it.

As an example, let's say I had a web site that sold rare items and an API that you could use to reserve an item. Maybe it has the signature:

HttpResponse<ItemReservation> CreateReservation(int itemId)

Now it's highly likely that users may find that they've been beaten to the punch by someone else. In this case, throwing an exception to be caught by an error handler to send a different response (maybe an HttpResponse<ItemReservationFailed>) to convey the failure would be nasty. So do I have to add structure to all my return types to carry failure information?