Dynamic error handling in Go (specifically the database / sql package)
Using the package database/sql
to look for things like sql.Exec
will return dynamically generated unreferenced errors like
"Error 1062: Duplicate entry '192' for key 'id'"
The problem is that it can also return errors like
"Error 1146: Table 'tbl' doesn't exist"
From the same call to sql.Exec
How can I explain the difference between these two errors without
- Compare strings or
- Pattern matching for error code
Or are these idiomatic viable solutions to this problem?
source to share
database / sql package does not solve this problem. This is a specific driver. For example, for mysql, you can use:
if mysqlError, ok := err.(*mysql.MySQLError); ok {
if mysqlError.Number == 1146 {
//handling
}
}
Alternatively, you can find a bug package like mysqlerr from VividCortex and use it:
if mysqlError, ok := err.(*mysql.MySQLError); ok {
if mysqlError.Number == mysqlerr.ER_NO_SUCH_TABLE {
//handling
}
}
It's not much better than pattern matching, but it seems to be more idiomatic.
source to share
I think there is no idiomatic solution there, but I wrote a simple function to get the error number, so you can easily compare them.
In this solution I assume that the construction of the error message is always the same: "Error-some number here-: Error description".
If there is no number in the error or something went wrong, it returns 0.
func ErrorCode(e error) int {
err := e.Error() //the description of the error
if len(err) < 6 { //if its too small return 0
return 0
}
i := 6 //Skip the part "Error "
for ; len(err) > i && unicode.IsDigit(rune(err[i])); i++ {
} // Raising i until we reach the end of err or we reach the end of error code
n, e := strconv.Atoi(string(err[6:i])) //convert it to int
if e != nil {
return 0 //something went wrong
}
return n //return the error code
}
Go to the playing field: http://play.golang.org/p/xqhVycsuyI
source to share