首页 > 解决方案 > NodeJS - 抛出错误作为控制流的一种方式是什么?

问题描述

这个问题很相似,但答案是特定于sails:NodeJS best practice: Errors for flow control?

我来自使用 C# 开发 REST API 的背景。在 C# 中,当出现操作“错误”(我故意在引号中使用错误)时,我们只是将常量或键返回到消息查找表。根据返回的消息,路由层将向用户返回适当的状态代码(200、404 等)。

以登录为例。假设有人登录到服务器,并且该帐户不存在。这不是一件不寻常的事情,因此抛出错误没有多大意义。

现在,我正在编写 Node 应用程序,我很沮丧。似乎常见的做法是在发生任何意外情况时到处抛出错误。这对于诸如数据库无法检索已知存在的帐户或捕获语法错误之类的事情是有意义的。但是对于像用户输入错误的用户名/密码这样的事情,抛出错误似乎有点过头了。

然后考虑一个有错误报告中间件的情况。对于语法错误,您可能想要记录堆栈跟踪,而您永远不想因为密码错误而这样做。通过对控制流使用错误,输入错误密码的用户可能会占用与记录关键数据库异常相同的服务器资源。您可以扩展 Error 类并打开错误类型,但这似乎很草率。

最后,一些解决方案只是直接返回带有状态代码的 ExpressJS 响应,但我并不总是希望在数据库中找不到用户的每种情况下都使用相同的状态代码。也许我想为用户个人资料页面返回 404,为登录失败返回 400。

有没有其他人遇到过这个问题,如果有,你是如何处理的(双关语)?

更新

这是一些代码来演示我的解决方案的外观。我发明了一个名为 的新类Goof,它就像一个错误,但它用于可能出现结果的情况。例如,错误的登录凭据将是以下类型Goof

// constants.js.
const WRONG_PASSWORD = 1;
const USERNAME_DOES_NOT_EXIST = 1;

// goof.js.
class Goof {
    constructor(message) {
        this.message = message;
    }
}

// Inside express route.
const username = req.body.username;
const password = req.body.password;
const result = await signInUser(username, password);
if(typeof(result) === Goof) {
    if(result.status === constants.WRONG_PASSWORD) {
        res.sendStatus(400);
        return;
    }

    if(result.status === constants.USERNAME_DOES_NOT_EXIST) {
        res.sendStatus(400)
        return;
    }

    else {
        throw new Error('A Goof was returned but not handled properly');
    }
} else {
    res.json(result);
}

与抛出和捕获错误相比,这有什么优点/缺点?

标签: node.jsexpresserror-handling

解决方案


推荐阅读