Custom Error Responses

Johannes Rudolph edited this page Aug 14, 2013 · 6 revisions

. . .

Deprecation Note

This documentation is for release 0.9.0 (from 03/2012), which is built against Scala 2.9.1 and Akka 1.3.1 (see Requirements for more information). Most likely, this is not the place you want to look for information. Please turn to the main spray site at http://spray.io for more information about other available versions.

. . .

All predefined route directives produce proper HTTP status codes and error messages according to the requirements of the HTTP spec if something goes wrong. For example:

  • If the request cannot be handled because no path filter matched spray will produce a 404 Not Found error.
  • If the path matched but no route for the requests HTTP method is defined spray will produce a 405 Method Not Allowed error.
  • If the unmarshaller in your routes cannot deserialize the request content the response will be a 415 Unsupported Media Type error.
  • If the marshallers responsible for serialization of your custom object cannot produce a content type that the client accepts spray will return a 406 NotAcceptable error.

As discussed in the section about Rejections errors in spray are handled by a two-level logic. First the error is wrapped in a Rejection, where it is stored and maybe overcome by another subsequent route in the route structure that is able to successfully handle the request. If the rejection cannot be overcome it is the job of the HttpService to generate an error response for the set of rejections created by the routing structure.

Customizing Error Responses

When you create an HttpService you can optionally pass a custom RejectionHandler to the constructor. A RejectionHandler is defined like this:

type RejectionHandler = PartialFunction[List[Rejection], HttpResponse]

The cc.spray.RejectionHandler.Default partial function implements the default translations. A good approach is to write translations for "interesting" rejections yourself and delegate to the default handler in all other cases:

val myRejectionHandler: RejectionHandler = {
  case AuthenticationFailedRejection(realm) :: _ =>
    HttpResponse(Unauthorized, "Naaah, boy!!")
}

val myService = Actor.actorOf {
    new HttpService(
      route = mainModule.route,
      rejectionHandler = myRejectionHandler
        orElse RejectionHandler.Default
    )
}