diff --git a/internal/errkind/errkind.go b/internal/errkind/errkind.go index 74e9099..f1d719d 100644 --- a/internal/errkind/errkind.go +++ b/internal/errkind/errkind.go @@ -17,13 +17,20 @@ import ( // HTTPStatuser is implemented by errors that are a non-2xx answer from a service. type HTTPStatuser interface{ HTTPStatus() int } -// Of is the kind of err: "timeout", "canceled", "http_", "network", or "error". +// SQLStater is implemented by database errors that carry a SQLSTATE (pgx's PgError does). +// The five-character code is a fixed vocabulary; the error's message is not: Postgres quotes +// the offending value, which for a transcript row is transcript text. +type SQLStater interface{ SQLState() string } + +// Of is the kind of err: "timeout", "canceled", "http_", "sql_", "network", +// or "error". // It is empty for nil. func Of(err error) string { if err == nil { return "" } var hs HTTPStatuser + var ss SQLStater var ne net.Error switch { case errors.Is(err, context.DeadlineExceeded): @@ -32,6 +39,8 @@ func Of(err error) string { return "canceled" case errors.As(err, &hs): return fmt.Sprintf("http_%d", hs.HTTPStatus()) + case errors.As(err, &ss) && ss.SQLState() != "": + return "sql_" + ss.SQLState() case errors.As(err, &ne): if ne.Timeout() { return "timeout"