Use a better framework? In any good framework, returning a json body with a status code should be a one-liner.
One topic the article didn't even touch was flagging bad parameters in the request which didn't make sense on the application level. HTTP has 422 for that. I commonly write things like
validate_my_param($c->req->params->{format})
or $c->detach(HTTP => 422, ['Invalid format']);
(the HTTP view renders that string either as text/plain or json as {"message":"Invalid format"} depending on the accept header of the request.)
I've used that for years and been quite happy with the downstream results.
Edit: I should elaborate on the downstream results.
On the javascript side, the ajax methods often contain separate success and failure callbacks. You often need to handle the failure callback to ensure the user knows that something broke. If you also have an error path in the success callback, it clutters the code.
ajax({
success(data, ...) {
if (data.wasActuallyAnError) {
// lines
// of code
// to handle
// the error
}
else useTheData(data);
},
error(response, ...) {
// lines
// of code
// to handle
// the error
}
})
vs.
ajax({
success(data, ...) {
useTheData(data);
},
error(response, ...) {
// lines
// of code
// to handle
// the error
}
})
This problem is not insurmountable of course. you could wrap up your error code in helper functions and reduce the boilerplate. You could write a completely generic error handler for your front-end framework and automatically include it in all ajax calls. You could also write a custom ajax method that interprets the 200 status error messages and diverts to the error callback. But I still think the 404/422 status code is a better pattern to start from, since most of the client-side frameworks I've used switch code paths based on the status code.