Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DB error standardization #23

Merged
merged 3 commits into from
Oct 21, 2018
Merged

DB error standardization #23

merged 3 commits into from
Oct 21, 2018

Conversation

derkan
Copy link
Contributor

@derkan derkan commented Oct 11, 2018

Added a new ParseError method to Adapter interface which parses adapter's error and provides error standardization like:

import (
	"github.com/samonzeweb/godb/dberror"
)
func () string{ 
    if err := db.Insert(&Book).Do(); err!=nil {
        if e, ok := err.(dberror.UniqueConstraint); ok {
		return fmt.Sprintf("Record with this value already exists, field:%s",e.Field)
	}
	if e, ok := err.(dberror.CheckConstraint); ok {
		return fmt.Sprintf("Record data for column %s is not valid",e.Field)
	}
	if e, ok := err.(dberror.ForeignKeyConstraint); ok {
		return fmt.Sprintf("Referenced value error for column: %s", e.Field)
	}
        return err.Error()
    }
}

@samonzeweb
Copy link
Owner

Hi Derkan,

I like it, really useful, easily expandable, original errors are preserved, types are common between adapters 👍

But there is one downside : public API is broken. Yes I'm a pain in the neck in this case, sorry. But I think the problem is rather simple to solve.

For a v2, something like this will simply be good enough. For now we can not break others code. But as it's really useful we can add this behaviour as optional. The idea is to have a method UseErrorParser to set a flag. According to its value you either returns the raw error (legacy mode, by default) or new parsed errors :

type DB struct {
	...
	// Optional error parsing by adapters (false by default = legacy mode)
	// Will probably be the default behaviour in new major release.
	useErrorParser bool
}

...

// UseErrorParser will allow adapters to parse errors and wrap ones returned by drivers
func (db *DB) UseErrorParser() {
	db.useErrorParser = true
}

The Clone method need to copy this new field.

In sqlrunner.gosomething like

	if err != nil {
		db.logExecutionErr(err, query, arguments)
		if db.useErrorParser {
			return nil, db.adapter.ParseError(err)
		} else {
			return nil, err
		}
	}

Is it ok for you ? Something I missed ?

Sam.

@derkan
Copy link
Contributor Author

derkan commented Oct 20, 2018

Good catch. 👍 Thank you. I've implemented changes as you suggested.

@samonzeweb samonzeweb merged commit a67ee86 into samonzeweb:master Oct 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants