1

I'm using OpenRasta 2.0 to build a REST API and its extensibility is fantastic - we've managed for instance to plug-in OAuth authentication using DotNetOpenAuth fairly painlessly.

However I've come to the point now where I need to define our responses for error conditions. We're adopting the standards regarding HTTP error codes - but I'm concious of returning meaningful responses as well, pretty much like Twitter (the perennial example of REST) does:

{
 "error":"This method requires authentication.",
 "request":"\/1\/statuses\/followers.json"
}

Is the best way to return an OperationResult from all of our handlers, manually capture exceptions and map to a ResponseResource? This seems to me to be a fair amount of overhead compared with how the rest of OpenRasta functions.

Or should we write some kind of contributor to capture exceptions thrown in the pipeline and globally handle the issues? Perhaps translating only exceptions of particular types (RestException?).

Basically I'm after a feeling for what the best practice for this would be and how others have handled it.

Thanks.

EDIT:

After looking at this for some time today I'm having trouble figuring out how to wrap the handler call - I've declared myself a OperationInterceptor derived class and have hooked that into the pipeline with ResourceSpace.Uses.PipelineContributor<OperationInterceptorContributor>() and set a custom dependency up ResourceSpace.Uses.CustomDependency<IOperationInterceptor, ExceptionHandlerInterceptor>(DependencyLifetime.PerRequest) but no matter in which of the methods I try and wrap in a try-catch, the exception still bubbles.

Is it RewriteOperation, BeforeExecute or AfterExecute that is the most appropriate place to trap - and if so can you give me a clue as to how to start?

Thanks.

Kieran Benton
  • 8,739
  • 12
  • 53
  • 77
  • 1
    Don't add the OperationInterceptorContributor, there's no need for that. You can either add your operation interceptor as an attribute on the method or the handler you want the functioanlity to work on, or simply register the interceptor in your IoC container for the IOperationInterceptor interface (and make it transient), and you're done, which you can either do in your IoC of choice or through the .Has.CustomDependency method. – SerialSeb Nov 17 '10 at 14:08
  • 1
    Seems I missed that one. It's in the rewrite, you wrap the original call (the delegate passed to the rewrite method) in your try/catch. – SerialSeb Feb 23 '11 at 15:09

1 Answers1

5

There's a couple of things you can do to achieve what you want.

First, you can build an IOperationInterceptor that wraps the call to your handler in a try/catch block, and assign the correct OperationResult on the ICommunicationContext.

Then if you want this to be serialized in json, you'll want to assign the ResponseResource property of your operationresult to a type that describes your error (let's call it "TitsUpResource" for now).

Finally, register that type as a resource with no URI, so you can add the json codec to it

ResourceSpace.Has.ResourcesOfType().WithoutUri.TranscodedBy or whatever else you may want.

SerialSeb
  • 6,701
  • 24
  • 28
  • Lol outstanding answer, thanks Seb - who better to get it from than the man himself. +1 especially for TitsUpResource! – Kieran Benton Nov 16 '10 at 11:34
  • Would you mind looking at my further question in my edit? I can't get this working still. Thanks. – Kieran Benton Nov 16 '10 at 19:03
  • How do you enforce the `StatusCode` of the HTTP response when setting the `OperationResult` in an `IOperationInterceptor`? For me, it just reverts to 200. – Asbjørn Ulsberg Jul 07 '11 at 14:55
  • 1
    Hmm, in the interceptor you set the response on ICommunicationContext and you return false to prevent execution of the handler, it shouldnt revert anything – SerialSeb Jul 08 '11 at 13:40