func mainloop(db *sql.DB) {
type pushTask struct {
TaskId string
Uri string
}
stmt, err := db.Prepare("INSERT INTO ErrPushCache(TaskId, Uri) VALUES(?, ?)")
if err != nil {
log.Fatal("db.Prepare Failed ", err)
}
var (
mysqlOk bool = true
task pushTask
)
for {
task.TaskId = RandStringRunes(8)
task.Uri = RandStringRunes(16)
res, err := stmt.Exec(task.TaskId, task.Uri)
if err != nil {
if err == driver.ErrBadConn {
if mysqlOk {
log.Print("Connection with mysql seems down, %s", err.Error())
mysqlOk = false
os.Exit(1)
}
} else {
log.Print("Exec failed ", err)
}
time.Sleep(2 * time.Second)
continue
}
if !mysqlOk {
log.Print("Connection with mysql is ok now")
mysqlOk = true
}
lastId, err := res.LastInsertId()
if err != nil {
log.Print("LastInsertId failed ", err)
}
rowCnt, err := res.RowsAffected()
if err != nil {
log.Print("RowsAffected failed ", err)
}
log.Printf("ID = %d, affected = %d\n", lastId, rowCnt)
time.Sleep(20 * time.Second)
}
}
func main() {
db, err := sql.Open("mysql",
"rench:ren123@tcp(192.168.1.61:3306)/hunanTV")
if err != nil {
log.Fatal("sql.Open Failed ", err)
}
mainloop(db)
defer db.Close()
}
在mainloop函数中,如果mysql和客户端之间的连接中断,stmt.Exec将失败,它将返回错误,如何区分连接错误与其他错误。(错误== driver.ErrBadConn总是假)。
如果连接断开,则日志为:
2016/01/29 17:21:31执行失败拨号tcp 192.168.1.61:3306:getsockopt:连接被拒 2016/01/29 17:21:33执行失败拨号tcp 192.168.1.61:3306:getsockopt:连接被拒 2016/01/29 17:21:35执行失败拨号tcp 192.168.1.61:3306:getsockopt:连接被拒 2016/01/29 17:21:37执行失败拨号tcp 192.168.1.61:3306:getsockopt:连接被拒 2016/01/29 17:21:39执行失败拨号tcp 192.168.1.61:3306:getsockopt:连接被拒绝
...
答案 0 :(得分:0)
网络错误将是满足net.Error
接口的类型。
if err, ok := err.(net.Error); ok {
log.Println("network error:", err)
} else {
log.Println("other error:", err)
}
在大多数情况下,它并不重要,因为某些原因导致操作失败,无论如何都需要处理它。只有当您想根据您确实需要检查的网络错误采取不同的操作时。
答案 1 :(得分:-1)
这就是go的错误处理真的困扰我的地方。大多数情况下,实际的错误类型没有记录,所以你必须通过源代码并检查代码可以返回哪些错误。在某些情况下,这些只是通用字符串错误,因为代码是特定于平台的,因此错误也是特定于平台的。
您可以这样做,检查源代码,或者您可以打印错误类型以确切知道它是哪一个。
log.Printf("%T", err)