Exceptions/Catch an exception thrown in a nested call: Difference between revisions
Content added Content deleted
(Add Seed7 example) |
(→{{header|Go}}: Add a much simpler Go example.) |
||
Line 1,039: | Line 1,039: | ||
trace("complete") |
trace("complete") |
||
}</lang> |
}</lang> |
||
{{out}} |
|||
Output: |
|||
<pre> |
<pre> |
||
main: start |
main: start |
||
Line 1,074: | Line 1,074: | ||
main.main() |
main.main() |
||
t.go:61 +0x31 |
t.go:61 +0x31 |
||
</pre> |
|||
A simpler example, closer to the task description: |
|||
<lang go>package main |
|||
import "fmt" |
|||
type U0 struct { |
|||
error |
|||
s string |
|||
} |
|||
type U1 int |
|||
func foo2() { |
|||
defer func() { |
|||
// We can't just "catch" U0 and ignore U1 directly but ... |
|||
if e := recover(); e != nil { |
|||
// e can be of any type, check for type U0 |
|||
if x, ok := e.(*U0); ok { |
|||
// we can only execute code here, |
|||
// not return to the body of foo2 |
|||
fmt.Println("Recovered U0:", x.s) |
|||
// We could cheat and call bar the second time |
|||
// from here, if it paniced again (even with U0) |
|||
// it wouldn't get recovered. |
|||
// Instead we've split foo into two calls to foo2. |
|||
} else { |
|||
// ... if we don't want to handle it we can |
|||
// pass it along. |
|||
fmt.Println("passing on:", e) |
|||
panic(e) // like a "re-throw" |
|||
} |
|||
} |
|||
}() |
|||
bar() |
|||
} |
|||
func foo() { |
|||
// Call bar twice via foo2 |
|||
foo2() |
|||
foo2() |
|||
fmt.Println("not reached") |
|||
} |
|||
func bar() int { |
|||
return baz() |
|||
} |
|||
var done bool |
|||
func baz() int { |
|||
if !done { |
|||
done = true |
|||
panic(&U0{nil, "a message"}) |
|||
} |
|||
panic(U1(42)) |
|||
} |
|||
func main() { |
|||
foo() |
|||
fmt.Println("No panic") |
|||
}</lang> |
|||
[http://play.golang.org/p/X2pa8zE1Ce Run in Go Playground]. |
|||
{{out}} |
|||
<pre>Recovered U0: a message |
|||
passing on: 42 |
|||
panic: (main.U1) (0xfc140,0x2a) [recovered] |
|||
panic: (main.U1) (0xfc140,0x2a) |
|||
[... go-routine and stack trace omitted ...] |
|||
</pre> |
</pre> |
||