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

使用node-pg插入Postgres数据时如何处理报错避免应用崩溃

问题原因

该报错触发原因是workorders表的wo_id字段为主键,主键自带唯一非空约束,你提交的wo_num值已经存在于表中,触发了唯一约束校验失败。同时你的代码没有捕获异步操作抛出的异常,Node.js 环境中未处理的 Promise 拒绝会直接导致进程退出,表现为整个应用崩溃。

解决步骤
  • 第一步:给异步操作链添加错误捕获逻辑,所有数据库操作的异常都在捕获块中处理,返回对应提示给前端,避免异常冒泡到进程层面。
  • 第二步:如果业务逻辑支持同个工单下新增多个明细、不需要重复创建工单,可以修改插入工单的SQL语句,使用PostgreSQL原生的ON CONFLICT语法处理主键冲突,从根源避免该报错。

PostgreSQL中唯一约束冲突的错误码固定为23505,可以通过错误码判断错误类型,返回更精准的用户提示。

修改后的代码示例
const insertLineItemDB = (request, response) => {
    const { wo_num, description, due_date, cost } = request.body
    // 新增ON CONFLICT逻辑,主键冲突时跳过插入,不抛出错误
    const query1 = 'INSERT INTO workorders (wo_id, due_date, complete) VALUES ($1, $2, 0) ON CONFLICT (wo_id) DO NOTHING;';
    const query2 = 'INSERT INTO lineitems (wo_num, description, cost) VALUES ($1, $2, $3);';

    Promise.all([
        pool.query(query1, [wo_num, due_date]),
        pool.query(query2, [wo_num, description, cost])
    ]).then(function([query1Results, query2Results]) {
        response.status(201).send('Successfully inserted');
    }).catch(err => {
        // 捕获所有异常,避免进程崩溃
        console.error(err);
        if (err.code === '23505') {
            response.status(400).send('当前工单编号已存在,请勿重复提交');
        } else {
            response.status(500).send('服务器内部错误,请稍后重试');
        }
    })
}

如果你不需要冲突时跳过插入,也可以保留原SQL语句,只保留catch块的错误处理逻辑,同样可以避免应用崩溃,只给用户返回对应提示。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 06:48:01