mirror of https://github.com/jackc/pgx.git
Added understanding of error messages from server
parent
3e5096afef
commit
0e8f00e11c
21
conn.go
21
conn.go
|
@ -132,6 +132,8 @@ func (c *conn) processContextFreeMsg(t byte, r *messageReader) (err error) {
|
||||||
case 'S':
|
case 'S':
|
||||||
c.rxParameterStatus(r)
|
c.rxParameterStatus(r)
|
||||||
return nil
|
return nil
|
||||||
|
case errorResponse:
|
||||||
|
return c.rxErrorResponse(r)
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Received unknown message type: %c", t)
|
return fmt.Errorf("Received unknown message type: %c", t)
|
||||||
}
|
}
|
||||||
|
@ -190,6 +192,25 @@ func (c *conn) rxParameterStatus(r *messageReader) {
|
||||||
c.runtimeParams[key] = value
|
c.runtimeParams[key] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *conn) rxErrorResponse(r *messageReader) (err PgError) {
|
||||||
|
for {
|
||||||
|
switch r.readByte() {
|
||||||
|
case 'S':
|
||||||
|
err.Severity = r.readString()
|
||||||
|
case 'C':
|
||||||
|
err.Code = r.readString()
|
||||||
|
case 'M':
|
||||||
|
err.Message = r.readString()
|
||||||
|
case 0: // End of error message
|
||||||
|
return
|
||||||
|
default: // Ignore other error fields
|
||||||
|
r.readString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
panic("Unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
func (c *conn) rxBackendKeyData(r *messageReader) {
|
func (c *conn) rxBackendKeyData(r *messageReader) {
|
||||||
c.pid = r.readInt32()
|
c.pid = r.readInt32()
|
||||||
c.secretKey = r.readInt32()
|
c.secretKey = r.readInt32()
|
||||||
|
|
|
@ -34,6 +34,13 @@ func TestConnect(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestConnectWithInvalidUser(t *testing.T) {
|
||||||
|
_, err := Connect(map[string]string{"socket": "/private/tmp/.s.PGSQL.5432", "user": "invalid_user", "database": "pgx_test"})
|
||||||
|
pgErr := err.(PgError)
|
||||||
|
if pgErr.Code != "28000" {
|
||||||
|
t.Fatal("Did not receive expected error when connecting with invalid user")
|
||||||
|
}
|
||||||
|
}
|
||||||
func TestQuery(t *testing.T) {
|
func TestQuery(t *testing.T) {
|
||||||
conn, err := Connect(map[string]string{"socket": "/private/tmp/.s.PGSQL.5432", "user": "pgx", "database": "pgx_test"})
|
conn, err := Connect(map[string]string{"socket": "/private/tmp/.s.PGSQL.5432", "user": "pgx", "database": "pgx_test"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
11
messages.go
11
messages.go
|
@ -15,6 +15,7 @@ const (
|
||||||
rowDescription = 'T'
|
rowDescription = 'T'
|
||||||
dataRow = 'D'
|
dataRow = 'D'
|
||||||
commandComplete = 'C'
|
commandComplete = 'C'
|
||||||
|
errorResponse = 'E'
|
||||||
)
|
)
|
||||||
|
|
||||||
type startupMessage struct {
|
type startupMessage struct {
|
||||||
|
@ -50,3 +51,13 @@ type fieldDescription struct {
|
||||||
modifier int32
|
modifier int32
|
||||||
formatCode int16
|
formatCode int16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PgError struct {
|
||||||
|
Severity string
|
||||||
|
Code string
|
||||||
|
Message string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self PgError) Error() string {
|
||||||
|
return self.Severity + ": " + self.Message + " (SQLSTATE " + self.Code + ")"
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue