go

¿Cuándo debo usar panic vs log.fatalln() en golang?



(2)

panic se usa a menudo en pequeños programas para terminar el programa una vez que aparece un error que no sabe cómo manejar o que no quiere manejar. La desventaja del panic es exactamente eso: terminará el programa (en su mayoría, a menos que use la recover ). Por lo general, no es bueno usar el panic menos que tenga la intención de recuperarse de él o de que haya ocurrido algo de lo que realmente no pueda recuperarse, ni de lo contrario, puede terminar el programa con gracia. Considere, por ejemplo, una API que le ofrece funcionalidad, pero esa API tiene un panic en secreto en algún lugar y se da cuenta de que su programa termina en producción debido a esto. Por lo tanto, la "API de salida" de cualquier código que escriba debe recuperarse de los ataques de emergencia y devolver un error. Lo mismo se aplica a cualquier cosa que termine el programa.

Sin embargo, os.Exit () no puede recuperarse ni se ejecuta defers.

De la documentación en log.Fatalln() :

func Fatalln (v ... interface {}) Fatalln es equivalente a Println () seguido de una llamada a os.Exit (1).

El código fuente de Fatalln:

310 // Fatalln is equivalent to Println() followed by a call to os.Exit(1). 311 func Fatalln(v ...interface{}) { 312 std.Output(2, fmt.Sprintln(v...)) 313 os.Exit(1) 314 }

Parece que la principal diferencia es si el error es recuperable (o ahora se puede recuperar) (¿puede haber algo más significativamente diferente entre estos?

La definition la interfaz de Panic es:

215 // The panic built-in function stops normal execution of the current 216 // goroutine. When a function F calls panic, normal execution of F stops 217 // immediately. Any functions whose execution was deferred by F are run in 218 // the usual way, and then F returns to its caller. To the caller G, the 219 // invocation of F then behaves like a call to panic, terminating G''s 220 // execution and running any deferred functions. This continues until all 221 // functions in the executing goroutine have stopped, in reverse order. At 222 // that point, the program is terminated and the error condition is reported, 223 // including the value of the argument to panic. This termination sequence 224 // is called panicking and can be controlled by the built-in function 225 // recover. 226 func panic(v interface{})

Parece que el pánico no devuelve nada.

¿Es esa la principal diferencia? De lo contrario, parece que realizan la misma función en una aplicación, asumiendo que el pánico no se recupera.


  • El mensaje de registro va a la salida de registro configurada, mientras que el pánico solo se escribirá en stderr.

  • Panic imprimirá un seguimiento de pila, que puede no ser relevante para el error en absoluto.

  • Los programas de ejecución se ejecutarán cuando un programa entre en pánico, pero la llamada a os.Exit sale inmediatamente, y las funciones diferidas no se pueden ejecutar.

En general, utilice solo el panic para los errores de programación, donde el seguimiento de la pila es importante para el contexto del error. Si el mensaje no está dirigido al programador, simplemente está ocultando el mensaje en datos superfluos.