【问题标题】:Return async await try/catch thrown Error in ExpressJS response [duplicate]在 ExpressJS 响应中返回异步等待 try/catch 抛出错误 [重复]
【发布时间】:2021-01-12 16:25:05
【问题描述】:

使用 ExpressJS 4.16.0、NodeJS 10.15.0 和 KnexJS/Bookshelf,我试图弄清楚错误处理。

在我的应用程序中按预期捕获了错误,但服务器调用的响应中没有返回错误:return res.status(400).send(error);,而是得到了{}

我该如何解决这个问题?

用户路线:

router.post('/users/register',
  async function(req, res, next) {

    let user;

    try {
        user = await UserService.register(req.body);
    } catch (error) {
        console.log('Route: Catch: ', error); // Will display error from UserService Error here: "column users.emailll does not exist"

        return res.status(400).send(error); // Sends `{}` back
    }
    ...

用户服务:

...

try {
    user = await new User.User({
        emailll: userInput.email // Will throw error in "catch" below because "emailll" is invalid field
    }).fetch();
} catch (error) {
    // Throws error "column users.emailll does not exist"
    console.log('Service: Catch: ', error);
    throw new Error(error);
}

来自服务器的响应:{}

我假设由于async await 调用,错误正在某处被吞没?我需要使用this express-async-errors lib 之类的东西吗?

【问题讨论】:

  • 顺便说一句 throw new Error(error); 可能只是 throw error;

标签: javascript node.js express error-handling


【解决方案1】:
尝试发送错误消息而不是错误堆栈
return res.status(400).send(error.message);

【讨论】:

    【解决方案2】:

    res.send(err) 将在内部尝试将该对象转换为 JSON。默认情况下,JSON.stringify(obj) 仅包含目标对象上的可枚举属性,而您在错误对象上查找的常用属性默认情况下不可枚举。

    一种解决方法是使用您要发送的任何属性制作对象的副本,并且通常将它们分配默认为可枚举:

    let obj = {filename: error.filename, message: error.message};
    res.send(obj);
    

    通常,您不希望将有关服务器的内部详细信息作为错误消息发回,因此通常会隐藏实现细节并发送可能对客户端更有用的消息。

    所以,也许你只是想做:

    res.status(500).send(error.message);
    

    如果你真的想要 err 对象的所有属性,你也可以使用这样的辅助函数:

    function makeEnumerableCopy() {
        let descriptor = Object.getOwnPropertyDescriptors(err);
        // set all properties in the descriptor to be enumerable
        for (let key of Object.keys(descriptor)) {
            descriptor[key].enumerable = true;
        }
        return Object.defineProperties({}, descriptor);
    }
    

    这将制作对象的浅表副本并使所有“自己的”属性可枚举,因此您可以将其与res.send()JSON.stringify() 一起使用并获取所有属性。

    res.send(makeEnumerableCopy(err));
    

    【讨论】:

      猜你喜欢
      • 2018-12-20
      • 2010-11-09
      • 2019-02-11
      • 2016-01-26
      • 2020-03-08
      • 2017-02-06
      相关资源
      最近更新 更多