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

Express异步操作try-catch错误处理失效问题求助

问题描述

处理/products路径的POST请求时,尝试用try-catch捕获表单提交错误,但当提交不符合Schema规则的表单(比如未填写name)时,程序未按预期跳转,而是直接抛出错误。

Schema定义

const productSchema = new mongoose.Schema({
    name: {
        type: "String",
        required: true
    },
    price: {
        type: "Number",
        required: true,
        min: 0
    },
    category: {
        type: "String",
        lowercase: true,
        enum: ['fruit', 'vegetable', 'dairy']
    }
});

路由代码

app.post("/products", (req, res, next) => {
    try {
        const newProduct = new Product(req.body);
        newProduct.save();
        res.redirect(`/products/${newProduct._id}`);
    }
    catch (e) {
        next(e);
    }
});

错误处理中间件

app.use((err, req, res, next) => {
    const { status = 500, message = 'Something went wrong!' } = err;
    res.status(status).send(message);
});

疑问:为什么try-catch无法捕获该异步操作的错误,该如何解决?


问题原因与解决方法

原因

newProduct.save()是异步操作,它返回一个Promise。同步的try-catch只能捕获当前执行栈中的同步错误,无法捕获异步操作抛出的错误——因为save的错误会在后续事件循环中触发,此时try-catch代码块已经执行完毕,自然无法捕获。

另外,当前代码直接调用newProduct.save()却未等待其完成,就执行res.redirect,这不仅导致错误无法捕获,还可能因未完成保存就跳转,出现_id不存在的问题。

解决方法

有两种常用处理方式:

方法1:使用async/await(推荐)

将路由处理函数改为async函数,用await等待save操作完成,此时异步错误可被外层try-catch捕获:

app.post("/products", async (req, res, next) => {
    try {
        const newProduct = new Product(req.body);
        await newProduct.save(); // 等待保存完成
        res.redirect(`/products/${newProduct._id}`);
    }
    catch (e) {
        next(e); // 将错误传给错误处理中间件
    }
});

方法2:使用Promise的catch方法

若不想用async/await,可直接在save的Promise链上用catch捕获错误,再传给next:

app.post("/products", (req, res, next) => {
    const newProduct = new Product(req.body);
    newProduct.save()
        .then(() => {
            res.redirect(`/products/${newProduct._id}`);
        })
        .catch(e => {
            next(e);
        });
});

修改后,当Schema验证失败时,错误会被正确捕获并传给错误处理中间件,不会直接抛出到程序外层。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 11:28:06