使用无服务器HTTP发送自定义错误消息(快速)

时间:2019-06-03 14:44:27

标签: express lambda aws-api-gateway serverless-framework serverless

我需要从我的express应用程序以JSON格式发送自定义错误消息,并使用serverless-http在lambda函数中提供服务

如果我弄错了,请纠正我,但据我所知,我们需要使用LAMBA_PROXY APIG集成才能发送直接从lambda函数定义的自定义错误消息。

这是我到目前为止尝试过的:

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

这是API返回的内容(状态码为400)

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Error</title>
    </head>
    <body>
        <pre>Bad Request</pre>
    </body>
</html>

有什么线索介绍如何发送JSON格式的自定义响应?

更新: 经过更多测试后,我发现调用next(error)并没有到达最后一个错误处理程序


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);

1 个答案:

答案 0 :(得分:2)

(我刚刚回答了一个非常相似的问题here

是的,这在Express文档的Error Handling下进行了解释。

  

Express带有内置的错误处理程序,该错误处理程序可以处理应用程序中可能遇到的任何错误。默认的错误处理中间件功能已添加到中间件功能栈的末尾。

     

如果将错误传递给next(),并且没有在自定义错误处理程序中进行处理,则它将由内置错误处理程序进行处理;错误将与堆栈跟踪一起写入客户端。堆栈跟踪不包含在生产环境中。

要覆盖此处理程序,请参阅Express文档中标题为Writing error handlers的部分。

它说明:

  

以与其他中间件功能相同的方式定义错误处理中间件功能,除了错误处理功能具有四个参数而不是三个参数:(err, req, res, next)。例如:

app.use(function (err, req, res, next) {
  console.error(err.stack)
  res.status(500).send('Something broke!')
})
     

您先定义错误处理中间件,然后再定义其他app.use()并路由调用

因此,在您的情况下,如果要使用400和一些JSON进行响应,则可以编写如下内容:

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);