Beautiful errors with OpenRasta
Disclaimer: I’m an OpenRasta newbie so what follows may be completely wrong, but it appears to work for me.
Here’s a common feature of web services: when an error occurs during processing of a server request, the server should return a “nice” error message to the client. It goes without saying that the appropriate HTTP status code (4xx or 5xx) should be set.
A “nice” error message in this context means two things.
- The message is concise, human-readable and useful.
- The message contains no sensitive information. In other words, forwarding exceptions and stack traces are out of the question.
So how do we do this with OpenRasta?
Let’s look at a very common example and its solution. We’ve got an OperationInterceptor that does some work in its BeforeExecute method. This work has the potential to throw an exception, at which point the server should hold its hands up and say “sorry, I’m borked.” In other words we want to return an HTTP 500 Internal Server Error and possibly tell the user exactly what happened.
public class MyInterceptor : OperationInterceptor {
readonly ICommunicationContext _context;
public MyInterceptor(ICommunicationContext context) {
_context = context;
}
public override bool BeforeExecute(IOperation operation) {
try {
// ... do some stuff
} catch(Exception ex) {
// log all the gory details to the server log, available
// only to the system admins
LogToServerLog(ex);
// and display a nice message to the user, see below
// for an example of what this might say
string description = Strings.UserSafeErrorMessage;
// todo: how do we return this to OpenRasta?
}
return true;
}
}
The key to this problem is the // todo above, which we can fill in the with code below.
_context.OperationResult = new OperationResult.InternalServerError
{
ResponseResource = description;
}
This isn’t enough on its own, however. OpenRasta looks for a codec that matches the type of the object assigned to ResponseResource, and right now we haven’t registered a codec for the string type. Well that’s simple; we just add the following to our IConfigurationSource implementation:
ResourceSpace.Has .ResourcesOfType<string>() .WithoutUri .AsJsonDataContract();
Everything should now work, and (depending on how you’ve defined Strings.UserSafeErrorMessage) your response will be something like:
"An exception occurred while attempting to process the request. The operation will not be allowed. The server log contains a full exception report. Please notify the system administrator."
Awesome! But: there’s one more thing. This is probably the minimum amount of code you can get away with to achieve this, but it’s cheeky of us. We’re registering the string type as a resource! It’s probably better to create our own error type that will be more useful to all parties:
public class ServerError
{
public string Error { get; set; }
}
_context.OperationResult = new OperationResult.InternalServerError
{
ResponseResource = new ServerError { Error = description };
}
ResourceSpace.Has
.ResourcesOfType<ServerError>()
.WithoutUri
.AsJsonDataContract();
Which will give this output instead:
{"Error":"An exception occurred while attempting
to retrieve authorization information. The operation
will not be allowed. The server log contains a full
exception report. Please notify the system
administrator."}
That’s better.
Tweets
- Confession: This past year, I forgot that I'm a geek. I love technology. I am obsessed with software. And now it's time to be myself again!
- @Jermolene I can just imagine you outside with your laptop in a cardboard box. That is so completely you. Awesome.
- What's the best device for writing code outdoors in the sunshine? It's a beautiful day outside and I'm stuck indoors:(
- RT @randompunter: 10 Check Amazon.co.uk for cheap touchpad. 20 GOTO 10
- @IJohnson_TNF typical example of a beautiful Ruby blog - http://t.co/6lHzwX2 show me a .NET blog like that!
- @IJohnson_TNF I think the ruby people are just more shiny
- Blogs about Ruby are always so much prettier than blogs about .NET.
- @Oura_In_Flames It's not all that amazing, and very short!
- @Oura_In_Flames you played the Sonic Generations demo yet? ;)
- @Oura_In_Flames cheers for the birthday wishes, I've been too busy at work to even think about it...
- Reading Programming in Scala, and loving it!
- Learning Scala this weekend... Quite exciting!
- @serialseb okay, on Thursday ;)
- @Oura_In_Flames lol thanks
- After two weeks of dev, finally deployed my OpenRasta app on IIS. Feeling so pleased with myself!
- Arrived at work for 8am. First time that's happened in years!
- Last one in the office - again. #deadlines
- Finishing the evening with a book in bed!
- @Oura_In_Flames Then I must have done something terribly bad as I just got drenched
- Dear Mother Nature, please check your wall calendar is on the correct page. It's June, not January. Yes, June. #wet




