-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherrors.go
More file actions
121 lines (100 loc) · 3.37 KB
/
Copy patherrors.go
File metadata and controls
121 lines (100 loc) · 3.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package xpg
import (
"errors"
"io"
"net"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
)
const (
sqlStateUniqueViolation = "23505"
sqlStateForeignKeyViolation = "23503"
sqlStateNotNullViolation = "23502"
sqlStateCheckViolation = "23514"
sqlStateSerializationFailure = "40001"
sqlStateDeadlockDetected = "40P01"
sqlStateLockNotAvailable = "55P03"
sqlStateQueryCanceled = "57014"
sqlStateConnectionExceptionClass = "08"
)
// SQLState returns the PostgreSQL SQLSTATE code carried by err.
// It returns an empty string when the error tree does not contain a
// pgconn.PgError.
func SQLState(err error) string {
pgErr, ok := errors.AsType[*pgconn.PgError](err)
if !ok || pgErr == nil {
return ""
}
return pgErr.SQLState()
}
// IsNoRows reports whether err indicates that a query returned no rows.
func IsNoRows(err error) bool {
return errors.Is(err, pgx.ErrNoRows)
}
// IsUniqueViolation reports whether err is a PostgreSQL unique_violation.
func IsUniqueViolation(err error) bool {
return SQLState(err) == sqlStateUniqueViolation
}
// IsForeignKeyViolation reports whether err is a PostgreSQL
// foreign_key_violation.
func IsForeignKeyViolation(err error) bool {
return SQLState(err) == sqlStateForeignKeyViolation
}
// IsNotNullViolation reports whether err is a PostgreSQL not_null_violation.
func IsNotNullViolation(err error) bool {
return SQLState(err) == sqlStateNotNullViolation
}
// IsCheckViolation reports whether err is a PostgreSQL check_violation.
func IsCheckViolation(err error) bool {
return SQLState(err) == sqlStateCheckViolation
}
// IsSerializationFailure reports whether err is a PostgreSQL
// serialization_failure.
func IsSerializationFailure(err error) bool {
return SQLState(err) == sqlStateSerializationFailure
}
// IsDeadlock reports whether err is a PostgreSQL deadlock_detected error.
func IsDeadlock(err error) bool {
return SQLState(err) == sqlStateDeadlockDetected
}
// IsLockNotAvailable reports whether err is a PostgreSQL lock_not_available
// error.
func IsLockNotAvailable(err error) bool {
return SQLState(err) == sqlStateLockNotAvailable
}
// IsQueryCanceled reports whether PostgreSQL canceled the query.
//
// Client-side context cancellation remains available through errors.Is with
// context.Canceled or context.DeadlineExceeded.
func IsQueryCanceled(err error) bool {
return SQLState(err) == sqlStateQueryCanceled
}
// IsConnectionError reports whether err represents a PostgreSQL connection
// failure known to pgx or the Go networking stack.
func IsConnectionError(err error) bool {
if err == nil {
return false
}
if errors.Is(err, pgconn.ErrConnClosed) ||
errors.Is(err, io.EOF) ||
errors.Is(err, io.ErrUnexpectedEOF) {
return true
}
if _, ok := errors.AsType[*pgconn.ConnectError](err); ok {
return true
}
if _, ok := errors.AsType[*net.OpError](err); ok {
return true
}
state := SQLState(err)
return len(state) >= 2 &&
state[:2] == sqlStateConnectionExceptionClass
}
// IsRetryableTransaction reports whether PostgreSQL aborted the transaction
// because of a serialization failure or a deadlock.
//
// The entire transaction callback must still be safe to replay. Connection
// failures are deliberately not classified as transaction-retryable.
func IsRetryableTransaction(err error) bool {
return IsSerializationFailure(err) || IsDeadlock(err)
}