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 (<anonymous>) [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
相关产品推荐
相关产品推荐

