func (pe *PgError ) SQLState () string {
return pe .Code
}
type connectError struct {
config *Config
msg string
err error
}
func (e *connectError ) Error () string {
sb := &strings .Builder {}
fmt .Fprintf (sb , "failed to connect to `host=%s user=%s database=%s`: %s" , e .config .Host , e .config .User , e .config .Database , e .msg )
if e .err != nil {
fmt .Fprintf (sb , " (%s)" , e .err .Error())
}
return sb .String ()
}
func (e *connectError ) Unwrap () error {
return e .err
}
type connLockError struct {
status string
}
func (e *connLockError ) SafeToRetry () bool {
return true
}
func (e *connLockError ) Error () string {
return e .status
}
type parseConfigError struct {
connString string
msg string
err error
}
func (e *parseConfigError ) Error () string {
connString := redactPW (e .connString )
if e .err == nil {
return fmt .Sprintf ("cannot parse `%s`: %s" , connString , e .msg )
}
return fmt .Sprintf ("cannot parse `%s`: %s (%s)" , connString , e .msg , e .err .Error())
}
func (e *parseConfigError ) Unwrap () error {
return e .err
}
type pgconnError struct {
msg string
err error
safeToRetry bool
}
func (e *pgconnError ) Error () string {
if e .msg == "" {
return e .err .Error()
}
if e .err == nil {
return e .msg
}
return fmt .Sprintf ("%s: %s" , e .msg , e .err .Error())
}
func (e *pgconnError ) SafeToRetry () bool {
return e .safeToRetry
}
func (e *pgconnError ) Unwrap () error {
return e .err
}
type contextAlreadyDoneError struct {
err error
}
func (e *contextAlreadyDoneError ) Error () string {
return fmt .Sprintf ("context already done: %s" , e .err .Error())
}
func (e *contextAlreadyDoneError ) SafeToRetry () bool {
return true
}
func (e *contextAlreadyDoneError ) Unwrap () error {
return e .err
}
type writeError struct {
err error
safeToRetry bool
}
func (e *writeError ) Error () string {
return fmt .Sprintf ("write failed: %s" , e .err .Error())
}
func (e *writeError ) SafeToRetry () bool {
return e .safeToRetry
}
func (e *writeError ) Unwrap () error {
return e .err
}
func redactPW (connString string ) string {
if strings .HasPrefix (connString , "postgres://" ) || strings .HasPrefix (connString , "postgresql://" ) {
if u , err := url .Parse (connString ); err == nil {
return redactURL (u )
}
}
quotedDSN := regexp .MustCompile (`password='[^']*'` )
connString = quotedDSN .ReplaceAllLiteralString (connString , "password=xxxxx" )
plainDSN := regexp .MustCompile (`password=[^ ]*` )
connString = plainDSN .ReplaceAllLiteralString (connString , "password=xxxxx" )
brokenURL := regexp .MustCompile (`:[^:@]+?@` )
connString = brokenURL .ReplaceAllLiteralString (connString , ":xxxxxx@" )
return connString
}
func redactURL (u *url .URL ) string {
if u == nil {
return ""
}
if _ , pwSet := u .User .Password (); pwSet {
u .User = url .UserPassword (u .User .Username (), "xxxxx" )
}
return u .String ()