diff --git a/errors.go b/errors.go index 92cc9a361..a7da450ee 100644 --- a/errors.go +++ b/errors.go @@ -56,11 +56,15 @@ 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 string + Message string } func (me *MySQLError) Error() string { + if me.SQLState != "" { + return fmt.Sprintf("Error %d (%s): %s", me.Number, me.SQLState, me.Message) + } return fmt.Sprintf("Error %d: %s", me.Number, me.Message) } @@ -70,3 +74,10 @@ func (me *MySQLError) Is(err error) bool { } return false } + +func (me *MySQLError) IsWithSQLState(err error) bool { + if merr, ok := err.(*MySQLError); ok { + return merr.Number == me.Number && merr.SQLState == me.SQLState + } + return false +} diff --git a/errors_test.go b/errors_test.go index 3a1aef74d..671bee2d8 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{1234, "", "the server is on fire"} + otherInfraErr := &MySQLError{1234, "", "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{5678, "", "the server is on fire"} if errors.Is(infraErr, differentCodeErr) { t.Fatalf("expected errors to be different: %+v %+v", infraErr, differentCodeErr) } @@ -59,3 +59,16 @@ func TestMySQLErrIs(t *testing.T) { t.Fatalf("expected errors to be different: %+v %+v", infraErr, nonMysqlErr) } } + +func TestMySQLErrIsWithSQLState(t *testing.T) { + infraErr := &MySQLError{1234, "HY000", "the server is on fire"} + otherInfraErr := &MySQLError{1234, "HY000", "the datacenter is flooded"} + if !infraErr.IsWithSQLState(otherInfraErr) { + t.Errorf("expected errors to be the same: %+v %+v", infraErr, otherInfraErr) + } + + differentCodeErr := &MySQLError{1234, "42000", "the server is on fire"} + if infraErr.IsWithSQLState(differentCodeErr) { + t.Fatalf("expected errors to be different: %+v %+v", infraErr, differentCodeErr) + } +}