defer + recover 捕获所有异常

1)说明

go的异常捕获需要延迟函数defer + recover实现,在函数返回前,就可以捕获到, 这样其实比java的try catch更加优雅一点;

比如: web服务器程序崩溃前,需要做一些清理,那么就可以这样搞定;

还可以在捕获时,打印一些信息,继续panic,让错误往上抛

2)案例

package main

import (
	"fmt"
	"runtime"
)

type panicContext struct {
	function string
}

func ProtectRun(entry func()) {
	defer func() {
		err := recover()
		switch err.(type) {
		case runtime.Error:
			fmt.Println("runtime error:", err)
		default:
			fmt.Println("error:", err)
		}
	}()

	entry()
}

func g() {
	defer func() {
		err := recover()
		switch err.(type) {
		case runtime.Error:
			fmt.Println("g() runtime error:", err)
		default:
			fmt.Println("g() error:", err)
		}
	}()

	var b *int

	/*
		注意: 这行改为*b = 1/0 这样, 被除数是0,直接编译报错
		$ go build main.go
		# command-line-arguments
		.\main.go:38:8: division by zero
	*/
	*b = 1
}

func main() {
	fmt.Println("运行前")
	ProtectRun(func() {
		fmt.Println("手动宕机前")
		panic(&panicContext{"手动触发panic"})
		fmt.Println("手动宕机后")
	})

	ProtectRun(func() {
		fmt.Println("赋值宕机前")
		var a *int
		*a = 1
		fmt.Println("赋值宕机后")
	})

	g()

	fmt.Println("运行后")
}

/*
$ ./main.exe
运行前
手动宕机前
error: &{手动触发panic}
赋值宕机前
runtime error: runtime error: invalid memory address or nil pointer dereference
g() runtime error: runtime error: invalid memory address or nil pointer dereference
运行后
 */

猜你喜欢

转载自blog.csdn.net/themagickeyjianan/article/details/106980930
今日推荐