NodeJS API传入错误参数导致应用崩溃,如何返回错误且无需重启?
问题根因
- 你使用的
try/catch只能捕获同步代码抛出的错误,newProvider.save()是异步Promise操作,它抛出的错误属于异步回调栈内的异常,不会被外层同步的try/catch捕获,最终形成未处理的Promise拒绝(unhandledRejection),导致Node进程崩溃。 - 现有代码没有处理Mongoose校验失败、数据库操作失败等异常场景,错误直接抛出到进程层就会触发服务崩溃。
修复方案
方案1:在现有Promise链后追加.catch捕获异常
直接在then回调后添加catch回调处理异步错误,无需修改现有代码结构:
public addProviders(req: Request, res: Response, next: NextFunction) { const type = req.body.type, name = req.body.name; const newProvider = new Provider({ type, name }) newProvider.save() .then((provider: Object) => { if (provider) { const statusCode = res.statusCode; res.json({ statusCode, provider }) } }) // 新增catch捕获异步错误 .catch((err) => { // 返回400参数错误状态码+提示信息,也可以根据err对象返回具体字段错误原因 res.status(400).json({ statusCode: 400, msg: "参数错误,请检查传入的字段是否符合要求", error: err.message // 开发环境可返回具体错误内容,生产环境按需关闭 }) }) }
方案2:改用async/await语法,可直接配合try/catch捕获错误(更推荐,TS下类型提示更友好)
将方法改为异步方法,用await等待Promise执行完成,此时try/catch可以正常捕获异步错误:
// 方法前加async标识 public async addProviders(req: Request, res: Response, next: NextFunction) { try { const type = req.body.type, name = req.body.name; const newProvider = new Provider({ type, name }) const provider = await newProvider.save() if (provider) { const statusCode = res.statusCode; res.json({ statusCode, provider }) } } catch (e) { res.status(400).json({ statusCode: 400, msg: "请传入合法的参数", error: e instanceof Error ? e.message : "未知错误" }) } }
额外优化建议
- 可以在创建Provider实例前先对
req.body的参数做前置校验,比如判断type和name是否存在、格式是否符合要求,提前返回错误提示,不需要走到数据库操作层。 - 可以添加Express全局错误处理中间件,兜底捕获所有接口未处理的错误,避免服务直接崩溃:
// 全局错误中间件,放在所有路由定义之后 app.use((err: Error, req: Request, res: Response, next: NextFunction) => { console.error(err.stack) res.status(500).json({ msg: "服务内部错误", error: process.env.NODE_ENV === 'development' ? err.message : undefined }) })
内容的提问来源于stack exchange,提问作者JustAG33K
相关产品推荐
相关产品推荐

