为何recover 捕捉不到异常呢?

请大神指点迷津啊!

        func sql01() {
        var id []byte
        一条会出错的sql语句,包含没有转义的单引号,会发生异常
        sql := "select id from qiuduiku where name='ha'ha'"
       a, _ := db.Prepare(sql)
        a.QueryRow().Scan(&id)
        a.Close()
        //下面是捕捉异常的recover函数
        defer func() {
        if r := recover(); r != nil {
       fmt.Println("aaa")
       }
       }()
        }

运行后程序崩溃退出,但是为什么并没有捕捉到异常,打印出:aaa 呢???

下面是崩溃后的截图:
请大神指点,为何defer中的recover捕获不到异常???

共 4 个回复


heimeil

defer放前面,你这还没到defer就panic了

# 0

zsg

这是为什么?我也遇见了

# 1

slclub

recorver 必须放在一个defer 函数内
且要放在panic 之前
必须经过这 么一个函数栈调用才可以。

defer func() {
if r:= recover ) {
fmt.Println("FROM PANIC ERROR:",r)
}
}
# 2

Kiwi2021Kiwi

Recover捕获异常
天津快乐十分
通常来说,不应该对panic异常做任何处理,但有时,也许我们可以从异常中恢复,至少我们可以在程序崩溃前,做一些操作。举个例子,当web服务器遇到不可预料的严重问题时,在崩溃前应该将所有的连接关闭;如果不做任何处理,会使得客户端一直处于等待状态。幸运飞艇
如果web服务器还在开发阶段,服务器甚至可以将异常信息反馈到客户端,帮助调试。

如果在deferred函数中调用了内置函数recover,并且定义该defer语句的函数发生了panic异常,recover会使程序从panic中恢复,并返回panic value。导致panic异常的函数不会继续运行,但能正常返回。在未发生panic时调用recover,recover会返回nil。

让我们以语言解析器为例,说明recover的使用场景。考虑到语言解析器的复杂性,即使某个语言解析器目前工作正常,也无法肯定它没有漏洞。福彩双色球
因此,当某个异常出现时,我们不会选择让解析器崩溃,而是会将panic异常当作普通的解析错误,并附加额外信息提醒用户报告此错误。

func Parse(input string) (s *Syntax, err error) {
defer func() {
if p := recover(); p != nil {
err = fmt.Errorf("internal error: %v", p)
}
}()
// ...parser...
}
deferred函数帮助Parse从panic中恢复。在deferred函数内部,panic value被附加到错误信息中;并用err变量接收错误信息,返回给调用者。技巧
我们也可以通过调用runtime.Stack往错误信息中添加完整的堆栈调用信息。
澳洲幸运

# 3