package pgconn
import (
)
func ( error) bool {
var interface{ () bool }
if errors.As(, &) {
return .()
}
return false
}
func ( error) bool {
var *errTimeout
return errors.As(, &)
}
type PgError struct {
Severity string
SeverityUnlocalized string
Code string
Message string
Detail string
Hint string
Position int32
InternalPosition int32
InternalQuery string
Where string
SchemaName string
TableName string
ColumnName string
DataTypeName string
ConstraintName string
File string
Line int32
Routine string
}
func ( *PgError) () string {
return .Severity + ": " + .Message + " (SQLSTATE " + .Code + ")"
}
func ( *PgError) () string {
return .Code
}
type ConnectError struct {
Config *Config
err error
}
func ( *ConnectError) () string {
:= fmt.Sprintf("failed to connect to `user=%s database=%s`:", .Config.User, .Config.Database)
:= .err.Error()
if strings.Contains(, "\n") {
return + "\n\t" + strings.ReplaceAll(, "\n", "\n\t")
} else {
return + " " +
}
}
func ( *ConnectError) () error {
return .err
}
type perDialConnectError struct {
address string
originalHostname string
err error
}
func ( *perDialConnectError) () string {
return fmt.Sprintf("%s (%s): %s", .address, .originalHostname, .err.Error())
}
func ( *perDialConnectError) () error {
return .err
}
type connLockError struct {
status string
}
func ( *connLockError) () bool {
return true
}
func ( *connLockError) () string {
return .status
}
type ParseConfigError struct {
ConnString string
msg string
err error
}
func (, string, error) error {
return &ParseConfigError{
ConnString: ,
msg: ,
err: ,
}
}
func ( *ParseConfigError) () string {
:= redactPW(.ConnString)
if .err == nil {
return fmt.Sprintf("cannot parse `%s`: %s", , .msg)
}
return fmt.Sprintf("cannot parse `%s`: %s (%s)", , .msg, .err.Error())
}
func ( *ParseConfigError) () error {
return .err
}
func ( context.Context, error) error {
var net.Error
if errors.As(, &) && .Timeout() {
if .Err() == context.Canceled {
return context.Canceled
} else if .Err() == context.DeadlineExceeded {
return &errTimeout{err: .Err()}
} else {
return &errTimeout{err: }
}
}
return
}
type pgconnError struct {
msg string
err error
safeToRetry bool
}
func ( *pgconnError) () string {
if .msg == "" {
return .err.Error()
}
if .err == nil {
return .msg
}
return fmt.Sprintf("%s: %s", .msg, .err.Error())
}
func ( *pgconnError) () bool {
return .safeToRetry
}
func ( *pgconnError) () error {
return .err
}
type errTimeout struct {
err error
}
func ( *errTimeout) () string {
return fmt.Sprintf("timeout: %s", .err.Error())
}
func ( *errTimeout) () bool {
return SafeToRetry(.err)
}
func ( *errTimeout) () error {
return .err
}
type contextAlreadyDoneError struct {
err error
}
func ( *contextAlreadyDoneError) () string {
return fmt.Sprintf("context already done: %s", .err.Error())
}
func ( *contextAlreadyDoneError) () bool {
return true
}
func ( *contextAlreadyDoneError) () error {
return .err
}
func ( context.Context) ( error) {
return &errTimeout{&contextAlreadyDoneError{err: .Err()}}
}
func ( string) string {
if strings.HasPrefix(, "postgres://") || strings.HasPrefix(, "postgresql://") {
if , := url.Parse(); == nil {
return redactURL()
}
}
:= regexp.MustCompile(`password='[^']*'`)
= .ReplaceAllLiteralString(, "password=xxxxx")
:= regexp.MustCompile(`password=[^ ]*`)
= .ReplaceAllLiteralString(, "password=xxxxx")
:= regexp.MustCompile(`:[^:@]+?@`)
= .ReplaceAllLiteralString(, ":xxxxxx@")
return
}
func ( *url.URL) string {
if == nil {
return ""
}
if , := .User.Password(); {
.User = url.UserPassword(.User.Username(), "xxxxx")
}
return .String()
}
type NotPreferredError struct {
err error
safeToRetry bool
}
func ( *NotPreferredError) () string {
return fmt.Sprintf("standby server not found: %s", .err.Error())
}
func ( *NotPreferredError) () bool {
return .safeToRetry
}
func ( *NotPreferredError) () error {
return .err
}
type PrepareError struct {
err error
ParseComplete bool
}
func ( *PrepareError) () string {
if .ParseComplete {
return fmt.Sprintf("prepare failed after ParseComplete: %s", .err.Error())
}
return .err.Error()
}
func ( *PrepareError) () error {
return .err
}