Gestione delle eccezioni e dello stack di svolgimento in r
-
12-12-2019 - |
Domanda
Per configurare un'interfaccia di gestione delle eccezioni coerenti per i miei colleghi "e i miei script r, vorrei utilizzare la seguente struttura trycatchatch.
- .
- Un trycatch esterno è avvolto attorno a un determinato script r. È usato per catturare e gestire errori fatali che richiedono lo script di abortire.
- comandi trycatch specifici dell'utente all'interno degli script dell'utente. Questi dovrebbero prendere e, possibilmente, gestire
- .
- 2a. Errori non fatali, in cui nessun aborto di script è necessario
- 2b. Errori fatali che richiedono la sceneggiatura di abortire. L'errore è gestito dal trycatch esterno [vedere 1.]
- 2c. Errori fatali con ulteriori informazioni sull'errore. Errore maneggiato da esterno trycatch.
Il seguente codice è come implementerò queste funzionalità. Tuttavia, dal momento che non sono un esperto in r, vorrei chiedere se questo è un buon approccio. In particolare:
Q1. È OK non specificare un gestore di errore nel trycatch interno e attendere che il trycatch esterno gestire quell'errore (vedere 2b. Sopra e codice sotto)?
Q2. È ritornare lo stesso errore (vedi 2c. Sopra / sotto) all'interno di un gestore corretto / considerato buon stile di codifica?
Grazie!
.#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);} )
Soluzione
È perfettamente multa per prendere solo alcuni errori, lasciando altro per il gestore esterno o nessun gestore.Il sistema di errore è un po 'più flessibile di solito usato, quindi per il re-lancio di un errore si potrebbe pensare di creare il tuo tipo di errore
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)))
}
.
e lancio e / o gestire quello
tryCatch(vec*parameter1, error=function(e) {
err <- ourError(e, "addition fatal info; script aborted")
stop(err)
})
.
Un vantaggio di questo è che è possibile specificare ulteriori comportamenti nel gestore di livello superiore, utilizzando la classe restituita da 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)
})
.