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

String 处理Go中的动态错误(特别是数据库/sql包),string,error-handling,go,String,Error Handling,Go,使用go中的数据库/sql包执行sql.Exec将返回动态生成的未引用错误,例如 "Error 1062: Duplicate entry '192' for key 'id'" "Error 1146: Table 'tbl' doesn't exist" 问题是它还可能返回错误,例如 "Error 1062: Duplicate entry '192' for key 'id'" "Error 1146: Table 'tbl' doesn't exist" 从同一调用sql.Exe

使用go中的
数据库/sql
包执行
sql.Exec
将返回动态生成的未引用错误,例如

"Error 1062: Duplicate entry '192' for key 'id'"
"Error 1146: Table 'tbl' doesn't exist"
问题是它还可能返回错误,例如

"Error 1062: Duplicate entry '192' for key 'id'"
"Error 1146: Table 'tbl' doesn't exist"
从同一调用
sql.Exec

我怎样才能在没有错误的情况下区分这两个错误呢

  • 字符串比较,或
  • 错误代码的模式匹配

  • 或者这些惯用的解决方案对这个问题是可行的吗?

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

    在这个解决方案中,我假设错误消息的结构总是相同的:“error-some number here-:error description”

    如果错误中没有数字或出现问题,则返回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
    }
    
    func ErrorCode(e error)int{
    err:=e.Error()//错误的描述
    if len(err)<6{//if太小返回0
    返回0
    }
    i:=6//跳过“错误”部分
    对于;len(err)>i&&unicode.IsDigit(rune(err[i]);i++{
    }//提升i直到到达错误结束或到达错误代码结束
    n、 e:=strconv.Atoi(字符串(err[6:i])//将其转换为int
    如果e!=nil{
    返回0//出现了问题
    }
    return n//返回错误代码
    }
    

    转到游乐场链接:

    数据库/sql包无法解决此问题。这是司机专用的。例如,对于mysql,您可以使用:

    if mysqlError, ok := err.(*mysql.MySQLError); ok {
        if mysqlError.Number == 1146 {
            //handling
        }
    }
    
    此外,您还可以找到一些错误常量包,如VictorCortex中的mysqlerr,并使用它:

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

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

    我认为Go的作者需要解决
    错误
    类型/包中的问题@BlinkyTop他们需要解决什么问题?您确实意识到,您得到的错误不是来自
    errors.New()
    函数吗?很明显,在这种情况下,错误类型对于Go最流行的mysql驱动程序的作者来说不合适,也不具有足够的描述性。他不得不在错误类型上破解出自己的版本,现在我必须对它进行类型断言,甚至知道它是什么。谢谢!我应该意识到要检查司机。我使用类型断言检查了一个解决方案,但只读取了
    sql
    包。对于将来遇到困难的用户,请确保还导入了“github.com/go-sql-driver/mysql”。