如何在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
相关产品推荐
相关产品推荐

