diff --git a/errors.go b/errors.go index 5bfd0f82..57e3fc5e 100644 --- a/errors.go +++ b/errors.go @@ -45,4 +45,6 @@ var ( ErrInvalidValueOfLength = errors.New("invalid association values, length doesn't match") // ErrPreloadNotAllowed preload is not allowed when count is used ErrPreloadNotAllowed = errors.New("preload is not allowed when count is used") + // ErrDuplicatedKey occurs when there is a unique key constraint violation + ErrDuplicatedKey = errors.New("duplicated key not allowed") ) diff --git a/gorm.go b/gorm.go index 37595ddd..b5d98196 100644 --- a/gorm.go +++ b/gorm.go @@ -347,6 +347,10 @@ func (db *DB) Callback() *callbacks { // AddError add error to db func (db *DB) AddError(err error) error { + if errTranslator, ok := db.Dialector.(ErrorTranslator); ok { + err = errTranslator.Translate(err) + } + if db.Error == nil { db.Error = err } else if err != nil { diff --git a/interfaces.go b/interfaces.go index cf9e07b9..3bcc3d57 100644 --- a/interfaces.go +++ b/interfaces.go @@ -86,3 +86,7 @@ type Rows interface { Err() error Close() error } + +type ErrorTranslator interface { + Translate(err error) error +} diff --git a/tests/error_translator_test.go b/tests/error_translator_test.go new file mode 100644 index 00000000..2e472e34 --- /dev/null +++ b/tests/error_translator_test.go @@ -0,0 +1,19 @@ +package tests_test + +import ( + "errors" + "testing" + + "gorm.io/gorm" + "gorm.io/gorm/utils/tests" +) + +func TestDialectorWithErrorTranslatorSupport(t *testing.T) { + translatedErr := errors.New("translated error") + db, _ := gorm.Open(tests.DummyDialector{TranslatedErr: translatedErr}) + + err := db.AddError(errors.New("some random error")) + if !errors.Is(err, translatedErr) { + t.Fatalf("expected err: %v got err: %v", translatedErr, err) + } +} diff --git a/utils/tests/dummy_dialecter.go b/utils/tests/dummy_dialecter.go index c89b944a..a2d9c33d 100644 --- a/utils/tests/dummy_dialecter.go +++ b/utils/tests/dummy_dialecter.go @@ -8,7 +8,9 @@ import ( "gorm.io/gorm/schema" ) -type DummyDialector struct{} +type DummyDialector struct { + TranslatedErr error +} func (DummyDialector) Name() string { return "dummy" @@ -92,3 +94,7 @@ func (DummyDialector) Explain(sql string, vars ...interface{}) string { func (DummyDialector) DataTypeOf(*schema.Field) string { return "" } + +func (d DummyDialector) Translate(err error) error { + return d.TranslatedErr +}