BlinkyTop
BlinkyTop

Reputation: 1144

Handling Dynamic Errors In Go (Specifically database/sql Package)

Using the database/sql package in go for things like sql.Exec will return dynamically generated, unreferenced errors such as

"Error 1062: Duplicate entry '192' for key 'id'"

The problem is that it can also return errors such as

"Error 1146: Table 'tbl' doesn't exist"

From the same call to sql.Exec

How can I tell the difference between these two errors without

  1. String comparison, or
  2. Pattern matching for error code

Or are those idiomatic viable solutions for this problem?

Upvotes: 8

Views: 7772

Answers (2)

vladwd
vladwd

Reputation: 176

database/sql package does not solve this problem. It's driver specific. For example, for mysql you can use:

if mysqlError, ok := err.(*mysql.MySQLError); ok {
    if mysqlError.Number == 1146 {
        //handling
    }
}

Also, you can find some error constant 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 seems to be more idiomatic.

Upvotes: 16

mraron
mraron

Reputation: 2551

I think there's no idiomatic solution, but I wrote a simple function for getting 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's 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 playground link: http://play.golang.org/p/xqhVycsuyI

Upvotes: 0

Related Questions