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

如何在Golang中检测Postgres通过RAISE EXCEPTION抛出的自定义异常?

在Go中通过pgx检测PostgreSQL触发器抛出的特定异常

我在Golang中使用pgx库操作PostgreSQL,编写了如下PL/pgSQL触发器函数:

CREATE OR REPLACE FUNCTION foo() 
RETURNS TRIGGER AS
$$
BEGIN
    IF (bar = 'baz') THEN
        -- 业务逻辑
    ELSE
        RAISE EXCEPTION 'oops error';
    END IF;
    RETURN NEW;
END;
$$
LANGUAGE plpgsql;

请问如何在Go代码中检测该触发器抛出的oops error异常?我当前的实现是硬编码错误消息,但想找不依赖硬编码的更优方法。当前代码如下:

errOops := errors.New("ERROR: oops error (SQLSTATE P0001)")
err := myDBFunc()
if errors.Is(err, errOops) {
    // 处理异常
}

更优实现方案:基于SQLSTATE或自定义标识检测

硬编码错误消息不可靠,一旦数据库消息格式、语言设置变更,代码就会失效。推荐用以下两种方式:

1. 利用自定义SQLSTATE码

PostgreSQL允许给自定义异常指定唯一的SQLSTATE(用户自定义范围是P0000到P0999),这是最稳定的检测方式。

先修改触发器函数,指定专属SQLSTATE:

CREATE OR REPLACE FUNCTION foo() 
RETURNS TRIGGER AS
$$
BEGIN
    IF (bar = 'baz') THEN
        -- 业务逻辑
    ELSE
        -- 指定自定义SQLSTATE为P0002
        RAISE EXCEPTION 'oops error' USING SQLSTATE='P0002';
    END IF;
    RETURN NEW;
END;
$$
LANGUAGE plpgsql;

然后在Go代码中,通过pgx提供的*pgconn.PgError类型断言,检查SQLState字段:

import (
    "errors"
    "github.com/jackc/pgx/v5/pgconn"
)

// ...

err := myDBFunc()
var pgErr *pgconn.PgError
if errors.As(err, &pgErr) {
    // 匹配自定义的SQLSTATE
    if pgErr.SQLState == "P0002" {
        // 处理oops error异常
    }
}

2. 附加自定义标识(适用于多异常区分)

如果需要在同一个SQLSTATE下区分多个异常,可以在抛出时添加自定义提示或详情:

RAISE EXCEPTION 'oops error' 
USING SQLSTATE='P0002', 
      HINT='error_code=oops_trigger';

然后在Go代码中读取Hint字段辅助判断:

import (
    "errors"
    "strings"
    "github.com/jackc/pgx/v5/pgconn"
)

// ...

err := myDBFunc()
var pgErr *pgconn.PgError
if errors.As(err, &pgErr) {
    if pgErr.SQLState == "P0002" && strings.Contains(pgErr.Hint, "error_code=oops_trigger") {
        // 处理对应异常
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 08:50:38