You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express.js控制器内错误处理:异步函数未终止致服务器崩溃

注册API错误处理导致服务器崩溃问题

我实现了用户注册API接口/register,该路由处理函数为异步函数,需在AuthController中调用异步函数进行密码哈希,路由代码如下:

authRouter.post('/register', async (req: Request, res: Response, next: NextFunction) => {
    const { username, password } = req.body;
    
    const hashedPassword = await AuthController.hashPassword(password, next);

    // 其他操作

在AuthController的hashPassword函数中,我通过抛出错误测试错误处理逻辑,代码如下:

const hashPassword = async (password: string, next: NextFunction): Promise<void> => {
    try {
        throw new Error('test error');
        //return await bcrypt.hash(password, 10);
    } catch(err) {
        next(err);
    }
} 

但测试API时服务器完全崩溃,日志如下:

[1] Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
[1]     at new NodeError (node:internal/errors:400:5)
[1]     at ServerResponse.setHeader (node:_http_outgoing:663:11)
[1]     at ServerResponse.header (C:\Users\renet\Desktop\git\rapidhcm-monorepo\api\node_modules\express\lib\response.js:794:10)
[1]     at ServerResponse.send (C:\Users\renet\Desktop\git\rapidhcm-monorepo\api\node_modules\express\lib\response.js:174:12)
[1]     at ServerResponse.json (C:\Users\renet\Desktop\git\rapidhcm-monorepo\api\node_modules\express\lib\response.js:278:15)
[1]     at ServerResponse.send (C:\Users\renet\Desktop\git\rapidhcm-monorepo\api\node_modules\express\lib\response.js:162:21)
[1]     at C:\Users\renet\Desktop\git\rapidhcm-monorepo\api\dist\src\routes\auth\auth.js:72:25
[1]     at Generator.next (&lt;anonymous&gt;)
[1]     at fulfilled (C:\Users\renet\Desktop\git\rapidhcm-monorepo\api\dist\src\routes\auth\auth.js:28:58)
[1]     at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
[1]   code: 'ERR_HTTP_HEADERS_SENT'
[1] }
[1]
[1] Node.js v18.13.0

我推测错误原因是:hashPassword函数触发catch后并未终止执行,路由处理函数继续执行后续的"其他操作"代码,而该部分最终尝试发送响应,导致重复发送响应头。

我可以在路由函数中添加try/catch块,但不想这么做,原因有二:

  • 我认为这是不良设计——将try/catch块放在独立函数中更便于代码阅读;
  • 由于无法读取try/catch块外部的变量,不得不为整个函数添加一个大的try/catch块。

补充说明:以下是"其他操作"的代码细节:

try {
        await User.create({ username, password: hashedPassword ?? 's' });
        res.send({ username, password, hashedPassword });
    } catch (error) {
        console.error('Something went wrong when adding a new user', error);
        res.status(400).send({
            message: 'User already exists in the database',
        });
    }

内容的提问来源于stack exchange,提问作者Damian Kowalski

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 00:01:28