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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 17:54:05