Recover() inside func inside func does not work

Hi, everybody. Please, help me to solve this problem. There is a snippet.
I don’t understand why capturePanicY() inside anonymous function does not recover. Why the result of recover() inside capturePanicY is nil?

package main

import (
	"fmt"
)

func capturePanicX() {
	if v := recover(); v != nil {
		fmt.Println("X recovered")
	}
}

func capturePanicY() {
	if v := recover(); v != nil {
		fmt.Println("Y recovered")
	}
}

func main() {
	defer capturePanicX()
	defer func() { capturePanicY() }()
	panic("just do it")
}

// X recovered

Hey @koorgoo, you should read Defer, Panic, and Recover .

One thing to note however, is that even if you called defer capturePanicX() twice, it would still only recover once, since once a function panics, it will call it’s deferred functions normally, but after calling the first recover, there is no longer a panic to recover from in the second defer statement since it’s already been recovered.

As for the reason why it won’t recover even if you only called defer func() { capturePanicY() }() by itself, here is a sentence from the article above:
Recover is only useful inside deferred functions. During normal execution, a call to recover will return nil and have no other effect., so in this case I believe the deferred function gets executed normally, but then inside it you are calling a different function in it’s own stack with normal execution, which therefore has no connection with the main function to help it recover.

The answer is a bit hidden in the Recover section of Effective Go:

Because recover always returns nil unless called directly from a deferred function, deferred code can call library routines that themselves use panic and recover without failing.

(Scroll down to the fifth paragraph - the second one after the first code snippet - to find this statement.)

EDIT: Was three minutes too late :slight_smile:

2 Likes

I think your explanation was better just by posting that one line from the effective go page (it’s been a while since I’ve read it) :stuck_out_tongue:

@christophberger, @radovskyb thank you for your answers.
@christophberger thank you for the best answer :slight_smile:

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.