Entendo o seguinte ponto em relação ao recover()
comportamento em Go.
recover()
Segue avaliação imediata, mas execução atrasada .
Então, se ele não for chamado dentro de uma função adiada (trecho de código 1), ele recover()
será avaliado naquele momento e, nesse ponto, ele ainda estará lá nil
e, portanto, nosso código entra em pânico.
Se for chamado dentro de uma função adiada, a chamada da função será registrada, mas recover()
será chamada depois que ocorrer panic
e será recuperada com sucesso.
package main
import "fmt"
func main() {
defer recover() // since not called inside a deferred func, it will not recover successfully
panic("This is a panic")
}
Agora, tendo isso em mente, escrevi o código abaixo.
import (
"fmt"
)
func main() {
defer func(){
customRecover()
}()
panic("This is a panic")
}
func customRecover(){
if r:= recover(); r!= nil{
fmt.Println("Custom Recovery for: ",r)
}
}
Pesquisei online o raciocínio e obtive a mesma resposta que
O valor de retorno de recover é nulo se qualquer uma das seguintes condições for atendida:
- o argumento do pânico era nulo;
- a goroutine não está em pânico;
- recover não foi chamado diretamente por uma função adiada.
Mas não consigo entender por que o segundo snippet não está funcionando?!?
Ela satisfaz todas as 3 condições estritamente falando. Há alguma ressalva que eu esteja esquecendo? Acho que a 3ª condição não é satisfeita porque ela não é chamada diretamente, mas por meio de uma chamada de função aninhada. Mas por que ela precisa estar dentro de deferred somente?