From 0e8599ad78ba26fb1424f4f5d54e5d8f22dd36f7 Mon Sep 17 00:00:00 2001 From: Thomas Posch Date: Mon, 11 Apr 2022 12:27:27 +0200 Subject: [PATCH] report SQLState in MySQLError to allow library users to distinguish user-defined from client / server errors --- errors.go | 9 +++++++-- errors_test.go | 6 +++--- packets.go | 11 ++++++----- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/errors.go b/errors.go index 92cc9a361..49aad7b5c 100644 --- a/errors.go +++ b/errors.go @@ -56,11 +56,16 @@ func SetLogger(logger Logger) error { // MySQLError is an error type which represents a single MySQL error type MySQLError struct { - Number uint16 - Message string + Number uint16 + SQLState [5]byte + Message string } func (me *MySQLError) Error() string { + if me.SQLState != [5]byte{} { + return fmt.Sprintf("Error %d (%s): %s", me.Number, string(me.SQLState[:]), me.Message) + } + return fmt.Sprintf("Error %d: %s", me.Number, me.Message) } diff --git a/errors_test.go b/errors_test.go index 3a1aef74d..43213f98e 100644 --- a/errors_test.go +++ b/errors_test.go @@ -43,13 +43,13 @@ func TestErrorsStrictIgnoreNotes(t *testing.T) { } func TestMySQLErrIs(t *testing.T) { - infraErr := &MySQLError{1234, "the server is on fire"} - otherInfraErr := &MySQLError{1234, "the datacenter is flooded"} + infraErr := &MySQLError{Number: 1234, Message: "the server is on fire"} + otherInfraErr := &MySQLError{Number: 1234, Message: "the datacenter is flooded"} if !errors.Is(infraErr, otherInfraErr) { t.Errorf("expected errors to be the same: %+v %+v", infraErr, otherInfraErr) } - differentCodeErr := &MySQLError{5678, "the server is on fire"} + differentCodeErr := &MySQLError{Number: 5678, Message: "the server is on fire"} if errors.Is(infraErr, differentCodeErr) { t.Fatalf("expected errors to be different: %+v %+v", infraErr, differentCodeErr) } diff --git a/packets.go b/packets.go index ab30601ae..003584c25 100644 --- a/packets.go +++ b/packets.go @@ -587,19 +587,20 @@ func (mc *mysqlConn) handleErrorPacket(data []byte) error { return driver.ErrBadConn } + me := &MySQLError{Number: errno} + pos := 3 // SQL State [optional: # + 5bytes string] if data[3] == 0x23 { - //sqlstate := string(data[4 : 4+5]) + copy(me.SQLState[:], data[4:4+5]) pos = 9 } // Error Message [string] - return &MySQLError{ - Number: errno, - Message: string(data[pos:]), - } + me.Message = string(data[pos:]) + + return me } func readStatus(b []byte) statusFlag {