'How to default to returning errors as JSON instead of HTML with express?
Express by default returns errors as HTML pages. As I'm developing a REST api, I want all my errors to be in JSON format. How can i configure express for this?
I expect the response to look something like this
{
"statusCode": 404,
"error": "Not Found"
}
but instead I get
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Cannot DELETE /object/</pre>
</body>
</html>
This is my basic app
export const app = express();
app.use(express.json());
app.get("/objects", listObjects);
app.get("/object/:id", getObject);
app.post("/object", createObject);
app.put("/object/:id", updateObject);
app.delete("/object/:id", deleteObject);
UPDATE: To clarify, it is not the errors from my handlers I want to handle as json. Doing that is pretty straight forward.
What I'm after is for express to stop returning html errors for unregistered handlers, like doing DELETE on /assessments, or GET on /anUnknownRoute
Solution 1:[1]
You add custom error handling middleware - which is regular middleware but with 4 arguments instead of 3 - to the middleware stack. In this error handler you use res.status(code).send(jsonResponse)
to send the json error.
A simple quick example that will always send status 500 JSON errors:
const bodyParser = require('body-parser')
const express = require('express')
const jsonErrorHandler = (err, req, res, next) => {
res.status(500).send({ error: err });
}
const app = express()
// The other middleware
app.use(bodyParser.json())
// Your handler
app.use(jsonErrorHandler)
Solution 2:[2]
You may simply add 'Content-Type: application/json'
to your response headers and write basically anything you want in JSON format, e.g.
function(err, req, res, next){
res.setHeader('Content-Type', 'application/json');
res.status(500);
res.send(JSON.stringify(error));
});
Or you can use res.json
instead. Please, see official doc for more detailed information: https://expressjs.com/en/api.html#res.json
If you want to return errors in JSON by default, then you may be interested in using default express error-handling mechanism: https://expressjs.com/en/guide/error-handling.html
Just pass an error
to the next
callback to go straight to the error-handler (skipping everything else in the queue in between) and add an error-handling middleware to the end of your middleware queue. This should do the trick.
P.S. From express.js FAQ:
In Express, 404 responses are not the result of an error, so the error-handler middleware will not capture them. This behavior is because a 404 response simply indicates the absence of additional work to do; in other words, Express has executed all middleware functions and routes, and found that none of them responded. All you need to do is add a middleware function at the very bottom of the stack (below all other functions) to handle a 404 response:
app.use(function (req, res, next) {
res.status(404).send("Sorry can't find that!")
})
Obviously, you may send a response in JSON format...
Solution 3:[3]
all you have to do for getting JSON response for errors is to add another argument in the route handler that will be a middle-ware function responsible for errors.
Ex: you have to modify this
app.get('/objects', listObjects);
to be like that:
app.get('/objects', listObjects, (err, req, res, next) => {
res.status(404).send({error: err.message})
});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | |
Solution 3 | Abanoub Fathy |