mirror of https://github.com/perkeep/perkeep.git
109 lines
1.7 KiB
Go
109 lines
1.7 KiB
Go
package pq
|
|
|
|
import (
|
|
"database/sql/driver"
|
|
"fmt"
|
|
"io"
|
|
"net"
|
|
"runtime"
|
|
)
|
|
|
|
const (
|
|
Efatal = "FATAL"
|
|
Epanic = "PANIC"
|
|
Ewarning = "WARNING"
|
|
Enotice = "NOTICE"
|
|
Edebug = "DEBUG"
|
|
Einfo = "INFO"
|
|
Elog = "LOG"
|
|
)
|
|
|
|
type Error error
|
|
|
|
type PGError interface {
|
|
Error() string
|
|
Fatal() bool
|
|
Get(k byte) (v string)
|
|
}
|
|
type pgError struct {
|
|
c map[byte]string
|
|
}
|
|
|
|
func parseError(r *readBuf) *pgError {
|
|
err := &pgError{make(map[byte]string)}
|
|
for t := r.byte(); t != 0; t = r.byte() {
|
|
err.c[t] = r.string()
|
|
}
|
|
return err
|
|
}
|
|
|
|
func (err *pgError) Get(k byte) (v string) {
|
|
v, _ = err.c[k]
|
|
return
|
|
}
|
|
|
|
func (err *pgError) Fatal() bool {
|
|
return err.Get('S') == Efatal
|
|
}
|
|
|
|
func (err *pgError) Error() string {
|
|
var s string
|
|
for k, v := range err.c {
|
|
s += fmt.Sprintf(" %c:%q", k, v)
|
|
}
|
|
return "pq: " + s[1:]
|
|
}
|
|
|
|
func errorf(s string, args ...interface{}) {
|
|
panic(Error(fmt.Errorf("pq: %s", fmt.Sprintf(s, args...))))
|
|
}
|
|
|
|
type SimplePGError struct {
|
|
pgError
|
|
}
|
|
|
|
func (err *SimplePGError) Error() string {
|
|
return "pq: " + err.Get('M')
|
|
}
|
|
|
|
func errRecoverWithPGReason(err *error) {
|
|
e := recover()
|
|
switch v := e.(type) {
|
|
case nil:
|
|
// Do nothing
|
|
case *pgError:
|
|
// Return a SimplePGError in place
|
|
*err = &SimplePGError{*v}
|
|
default:
|
|
// Otherwise re-panic
|
|
panic(e)
|
|
}
|
|
}
|
|
|
|
func errRecover(err *error) {
|
|
e := recover()
|
|
switch v := e.(type) {
|
|
case nil:
|
|
// Do nothing
|
|
case runtime.Error:
|
|
panic(v)
|
|
case *pgError:
|
|
if v.Fatal() {
|
|
*err = driver.ErrBadConn
|
|
} else {
|
|
*err = v
|
|
}
|
|
case *net.OpError:
|
|
*err = driver.ErrBadConn
|
|
case error:
|
|
if v == io.EOF || v.(error).Error() == "remote error: handshake failure" {
|
|
*err = driver.ErrBadConn
|
|
} else {
|
|
*err = v
|
|
}
|
|
|
|
default:
|
|
panic(fmt.Sprintf("unknown error: %#v", e))
|
|
}
|
|
}
|