aboutsummaryrefslogtreecommitdiffhomepage
path: root/testdata/recover.go
blob: ced90cfaeec3e6ebb29083f7b9b336e2a4546054 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main

func main() {
	println("# simple recover")
	recoverSimple()

	println("\n# recover with result")
	result := recoverWithResult()
	println("result:", result)

	println("\n# nested defer frame")
	nestedDefer()

	println("\n# nested panic: panic inside recover")
	nestedPanic()

	println("\n# panic inside defer")
	panicInsideDefer()

	println("\n# panic replace")
	panicReplace()
}

func recoverSimple() {
	defer func() {
		println("recovering...")
		printitf("recovered:", recover())
	}()
	println("running panic...")
	panic("panic")
}

func recoverWithResult() (result int) {
	defer func() {
		printitf("recovered:", recover())
	}()
	result = 3
	println("running panic...")
	panic("panic")
}

func nestedDefer() {
	defer func() {
		printitf("recovered:", recover())
	}()

	func() {
		// The defer here doesn't catch the panic using recover(), so the outer
		// panic should do that.
		defer func() {
			println("deferred nested function")
		}()
		panic("panic")
	}()
	println("unreachable")
}

func nestedPanic() {
	defer func() {
		printitf("recovered 1:", recover())

		defer func() {
			printitf("recovered 2:", recover())
		}()

		panic("foo")
	}()
	panic("panic")
}

func panicInsideDefer() {
	defer func() {
		printitf("recovered:", recover())
	}()
	defer func() {
		panic("panic")
	}()
}

func panicReplace() {
	defer func() {
		printitf("recovered:", recover())
	}()
	defer func() {
		println("panic 2")
		panic("panic 2")
	}()
	println("panic 1")
	panic("panic 1")
}

func printitf(msg string, itf interface{}) {
	switch itf := itf.(type) {
	case string:
		println(msg, itf)
	default:
		println(msg, itf)
	}
}