Returning JSON errors in a ZF2 application

If you have a standard ZF2 application and accept application/json requests in addition to application/html, then you have probably noticed that when an error happens, HTML is created, even though the client has requested JSON.

One way to fix this is to create a listener on MVC's render event to detect that an error has occurred and substitute a JsonModel in place of the ViewModel.

The easiest way to do this in your ApplicationModule.

Firstly, attach a lister to render:

Now write the error detector:

You'll also need some use statements:

(This code is heavily inspired from PhlyRestfully – Thanks Matthew!)

Essentially, we check that we are in an error situation and that the client wants JSON. If we are, we create a JsonModel and populate it information. I've used the fields from the draft Problem Details for HTTP APIs IETF spec as it seems sensible to do so.

Note though, that if you run this, you'll see that the response's content-type is application/json, not application/api-problem+json. You can't set this in onRenderError though as the view's JSON strategy will override it.

A brute-force solution to this is to override the content-type header in a listener on the finish event. Firstly we update onBootstrap():

Then we write the onFinish listener:

This method simply looks at the response and tries to guess if it's an api-problem. If it is, then it changes the content-type in the Response's header.

Now you're done.

You can test with curl:

which will return:

Of course, in an ideal world, someone would package this up into a module :)

4 thoughts on “Returning JSON errors in a ZF2 application

  1. These html errors bug me too. I wanted to test this out but am wondering where the best place would be to put onBootstrap(). You suggest Application/Module. The setup I've got here is a number of separate modules with admin and member controllers. All controllers inherit from a base controller (an abstract class) which itself extends Zend_Controller_Action. Should I put this code in the base controller then? Thanks!

  2. Is this still the way to return json errors in ZF2? Thinking this could be useful as a ZF2 module or simple library. Then I could add some tests around it. Will help older APIs built on ZF2 built before Apigility as Im assuming Apigility handles this eloquently. Haven't used apigility yet.

  3. There's probably other ways to do it, but I sill like this approach. I would guess you could simplify some of this by using some of Apigility's zf-campus components

  4. It does not make sense to first set the httpStatus response code and later update the response code with the exception code without updating the httpStatus.

Comments are closed.