Reputation: 2042
I need to send custom error message in JSON format, from my express app, served in a lambda function using serverless-http
Please correct me if i got it wrong, but as i understand it, we need to use LAMBA_PROXY APIG integration to be able to send custom error messages defined directly from a lambda function.
This is what i have tried so far:
res.status(400).json({ message: 'email already taken' });
serverless.yml
functions:
auth:
handler: src/express/auth/index.handler
name: ${self:service}-auth-${env:STAGE}
# warmup: true
integration: lambda-proxy
memorySize: 128
timeout: 15
events:
- http:
path: /auth/
method: ANY
cors: true
- http:
path: /auth/{any+}
method: ANY
cors: true
this is what the API is returning(with status code 400)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>Bad Request</pre>
</body>
</html>
Any leads, on how I can send a custom response, in JSON format?
update:
After more tests, I found out that calling next(error)
doesn't reach the last error handler
const register = async (req, res, next) {
try {
await verifyEmail(req.body.email);
const user = await Users.register(req.body);
const token = sign(user.attrs, {});
res.json({ token, user });
} catch (e) {
next(e);
}
};
const generalError = async (err, req, res, next) => {
// doesn't reach this part! :(
console.log('generalError handler', JSON.stringify(err));
res.status(errorOut.status).json(errorOut);
};
ApiRouter.post('/register', register);
app.use('/auth', ApiRouter);
app.use(generalError);
Upvotes: 1
Views: 1406
Reputation: 6491
(I just answered a very similar question here)
Yes, this is explained in the Express docs under Error Handling.
Express comes with a built-in error handler that takes care of any errors that might be encountered in the app. This default error-handling middleware function is added at the end of the middleware function stack.
If you pass an error to
next()
and you do not handle it in a custom error handler, it will be handled by the built-in error handler; the error will be written to the client with the stack trace. The stack trace is not included in the production environment.
To override this handler, refer to the section in the Express docs titled Writing error handlers.
It explains:
Define error-handling middleware functions in the same way as other middleware functions, except error-handling functions have four arguments instead of three:
(err, req, res, next)
. For example:app.use(function (err, req, res, next) { console.error(err.stack) res.status(500).send('Something broke!') })
You define error-handling middleware last, after other
app.use()
and routes calls
So in your case, if you wanted to respond with a 400 and some JSON, you might write something like this:
const serverless = require('serverless-http');
const express = require('express');
const app = express();
// Your middleware and other routes here
app.use(/* register your middleware as normal */);
// Finally, your custom error handler
app.use(function customErrorHandler(err, req, res, next) {
res.status(400).json({ message: 'email already taken' });
});
module.exports.handler = serverless(app);
Upvotes: 2