处理Go中的动态错误(特别是数据库/ sql包)

时间:2014-12-25 03:31:28

标签: string error-handling go

database/sql之类的内容中使用sql.Exec包将返回动态生成的,未引用的错误,例如

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

问题是它还可以返回错误,例如

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

从同一个电话sql.Exec

如果没有

,我如何区分这两个错误
  1. 字符串比较,或
  2. 错误代码的模式匹配
  3. 对于这个问题,那些惯用的可行解决方案是什么?

2 个答案:

答案 0 :(得分:8)

database / sql包没有解决这个问题。它是特定于驱动程序的。例如,对于mysql,您可以使用:

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

另外,你可以找到一些错误常量包,比如来自VividCortex的mysqlerr,并使用它:

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

它不比模式匹配好多少,但似乎更惯用。

答案 1 :(得分:0)

我认为没有惯用的解决方案,但我写了一个简单的函数来获取错误编号,因此您可以轻松地比较它们。

在此解决方案中,我假设错误消息的构造始终相同:"错误 - 此处有一些数字 - :错误描述"。

如果错误中没有数字或出现错误,则返回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
}

去游乐场链接:http://play.golang.org/p/xqhVycsuyI