Manejo de excepciones y pila desenfrenada en r
-
12-12-2019 - |
Pregunta
Para configurar una interfaz de manejo de excepciones coherentes para mis colegas y mis scripts, me gustaría emplear la siguiente estructura de Trycatch.
- Un intento exterior está envuelto alrededor de un guión R dado. Se utiliza para atrapar y manejar errores fatales que requieren que el script aborda.
- Comandos de Trycatch específicos del usuario dentro de los scripts del usuario. Estos deben atrapar y, posiblemente, manejar
- 2a. Errores no fatales, donde no es necesario el aborto de script
- 2b. Errores fatales que requieren que el script aborte. El error es manejado por el exterior Trycatch [ver 1.]
- 2c. Errores fatales con información adicional de errores. Error manejado por Outer Trycatch.
El siguiente código es cómo implementaría estas características. Sin embargo, dado que no soy un experto en R, me gustaría preguntar si este es un buen enfoque. Específicamente:
Q1. ¿Está bien no especificar un controlador de errores en el intrincador interno y esperar a que el intrincador externo maneje ese error (consulte 2b. Arriba y código a continuación)?
Q2. Se está repartiendo el mismo error (ver 2c. Arriba / abajo) Dentro de un controlador correcto / considerado buen estilo de codificación?
¡Gracias!
#outer tryCatch, see 1. tryCatch({ #user code block #2a. user specific tryCatch, object "vec" not defined tryCatch(print(vec),error=function(e) {print("Non-fatal error. Script execution continued.");print(e);}) #2b. user specific tryCatch tryCatch(vec*2) #2c. user specific tryCatch tryCatch(vec*parameter1, error=function(e) {print("Additional fatal error information. Script execution aborted.");stop(e);}) #end of user code block }, #outer tryCatch error handler in order to handle fatal errors error=function(e) {print("Fatal error");print(e);} )
Solución
Está perfectamente bien para atrapar solo algunos errores, dejando a otros para el controlador externo o ningún controlador en absoluto.El sistema de error es bastante más flexible de lo que se usa típicamente, por lo que para volver a lanzar un error, puede pensar en crear su propio tipo de error
ourError <-
function(original, message, class="ourError")
{
msg <- paste(message, conditionMessage(original), sep="\n ")
structure(list(message = msg, call = conditionCall(original)),
class = c(class, class(original)))
}
y lanzamiento y / o manejo de que
tryCatch(vec*parameter1, error=function(e) {
err <- ourError(e, "addition fatal info; script aborted")
stop(err)
})
Una ventaja de esto es que se pueden especificar comportamientos adicionales en el controlador de nivel superior, utilizando la clase devuelta por ourError()
tryCatch({
tryCatch(stop("oops"), error=function(e) {
err <- ourError(e, "addition fatal info; script aborted",
c("fatal", "ourError"))
stop(err)
})
}, ourError=function(err) {
message("We caught but didn't handle this:\n", err)
}, error =function(err) {
message("This one got away: ", err)
})