Die Angabe der globalen R-Option für die Behandlung nicht katastrophaler Fehler hat bei mir funktioniert, zusammen mit einem angepassten Workflow zum Speichern von Informationen über den Fehler und zum Überprüfen dieser Informationen nach dem Fehler. Ich verwende derzeit R Version 3.4.1. Im Folgenden habe ich eine Beschreibung des für mich funktionierenden Workflows sowie einen Code eingefügt, mit dem ich die globale Fehlerbehandlungsoption in R festgelegt habe.
Wie ich es konfiguriert habe, erstellt die Fehlerbehandlung auch eine RData-Datei, die alle Objekte im Arbeitsspeicher zum Zeitpunkt des Fehlers enthält. Dieser Speicherauszug kann mithilfe von R zurückgelesen werden, load()
und dann können die verschiedenen Umgebungen, wie sie zum Zeitpunkt des Fehlers vorhanden waren, mithilfe interaktiv überprüft werden debugger(errorDump)
.
Ich werde bemerken, dass ich in der traceback()
Ausgabe Zeilennummern von allen benutzerdefinierten Funktionen innerhalb des Stapels erhalten konnte, aber nur, wenn ich die keep.source=TRUE
Option beim Aufrufen source()
von benutzerdefinierten Funktionen verwendet habe, die in meinem Skript verwendet wurden. Ohne diese Option wurde durch Festlegen der globalen Fehlerbehandlungsoption wie unten die vollständige Ausgabe von traceback()
an ein Fehlerprotokoll mit dem Namen gesendet error.log
, aber die Zeilennummern waren nicht verfügbar.
Hier sind die allgemeinen Schritte, die ich in meinem Workflow unternommen habe, und wie ich nach einem nicht interaktiven R-Fehler auf den Speicherauszug und das Fehlerprotokoll zugreifen konnte.
Ich habe Folgendes oben in das Hauptskript eingefügt, das ich über die Befehlszeile aufgerufen habe. Dies legt die globale Fehlerbehandlungsoption für die R-Sitzung fest. Mein Hauptskript wurde aufgerufen myMainScript.R
. Die verschiedenen Zeilen im Code enthalten Kommentare, die beschreiben, was sie tun. Grundsätzlich wird mit dieser Option, wenn R auf einen stop()
auslösenden Fehler stößt , eine RData (* .rda) -Dump-Datei des Arbeitsspeichers in allen aktiven Umgebungen im Verzeichnis erstellt ~/myUsername/directoryForDump
und ein Fehlerprotokoll error.log
mit einigen nützlichen Informationen in das Verzeichnis geschrieben gleiches Verzeichnis. Sie können dieses Snippet ändern, um eine andere Fehlerbehandlung hinzuzufügen (z. B. einen Zeitstempel zur Speicherauszugsdatei und zu den Dateinamen des Fehlerprotokolls usw. hinzufügen).
options(error = quote({
setwd('~/myUsername/directoryForDump'); # Set working directory where you want the dump to go, since dump.frames() doesn't seem to accept absolute file paths.
dump.frames("errorDump", to.file=TRUE, include.GlobalEnv=TRUE); # First dump to file; this dump is not accessible by the R session.
sink(file="error.log"); # Specify sink file to redirect all output.
dump.frames(); # Dump again to be able to retrieve error message and write to error log; this dump is accessible by the R session since not dumped to file.
cat(attr(last.dump,"error.message")); # Print error message to file, along with simplified stack trace.
cat('\nTraceback:');
cat('\n');
traceback(2); # Print full traceback of function calls with all parameters. The 2 passed to traceback omits the outermost two function calls.
sink();
q()}))
Stellen Sie sicher, dass aus dem Hauptskript und allen nachfolgenden Funktionsaufrufen die Option keep.source=TRUE
verwendet wird , wenn eine Funktion bezogen wird. Das heißt, um eine Funktion zu beschaffen, würden Sie verwenden source('~/path/to/myFunction.R', keep.source=TRUE)
. Dies ist erforderlich, damit die traceback()
Ausgabe Zeilennummern enthält. Es sieht so aus, als könnten Sie diese Option möglicherweise auch global festlegen options( keep.source=TRUE )
, aber ich habe dies nicht getestet, um festzustellen, ob es funktioniert. Wenn Sie keine Zeilennummern benötigen, können Sie diese Option weglassen.
- Rufen Sie vom Terminal (außerhalb von R) das Hauptskript im Batch-Modus mit auf
Rscript myMainScript.R
. Dadurch wird eine neue nicht interaktive R-Sitzung gestartet und das Skript ausgeführt myMainScript.R
. Das in Schritt 1 angegebene Code-Snippet oben in myMainScript.R
legt die Fehlerbehandlungsoption für die nicht interaktive R-Sitzung fest.
- Stoßen Sie irgendwo in der Ausführung von auf einen Fehler
myMainScript.R
. Dies kann im Hauptskript selbst sein oder mehrere Funktionen tief verschachteln. Wenn der Fehler auftritt, wird die Behandlung wie in Schritt 1 angegeben ausgeführt und die R-Sitzung wird beendet.
- Eine RData-Dump-Datei mit dem Namen
errorDump.rda
und ein Fehlerprotokoll mit dem Namen error.log
werden in dem Verzeichnis erstellt, das in der '~/myUsername/directoryForDump'
Einstellung für die globale Fehlerbehandlungsoption angegeben ist .
In Ihrer Freizeit inspizieren error.log
Informationen über den Fehler zu überprüfen, einschließlich der Fehlermeldung selbst und der vollständigen Stack - Trace zu dem Fehler führt. Hier ist ein Beispiel für das Protokoll, das bei einem Fehler generiert wurde. Beachten Sie, dass die Zahlen nach dem #
Zeichen die Zeilennummern des Fehlers an verschiedenen Stellen im Aufrufstapel sind:
Error in callNonExistFunc() : could not find function "callNonExistFunc"
Calls: test_multi_commodity_flow_cmd -> getExtendedConfigDF -> extendConfigDF
Traceback:
3: extendConfigDF(info_df, data_dir = user_dir, dlevel = dlevel) at test_multi_commodity_flow.R#304
2: getExtendedConfigDF(config_file_path, out_dir, dlevel) at test_multi_commodity_flow.R#352
1: test_multi_commodity_flow_cmd(config_file_path = config_file_path,
spot_file_path = spot_file_path, forward_file_path = forward_file_path,
data_dir = "../", user_dir = "Output", sim_type = "spot",
sim_scheme = "shape", sim_gran = "hourly", sim_adjust = "raw",
nsim = 5, start_date = "2017-07-01", end_date = "2017-12-31",
compute_averages = opt$compute_averages, compute_shapes = opt$compute_shapes,
overwrite = opt$overwrite, nmonths = opt$nmonths, forward_regime = opt$fregime,
ltfv_ratio = opt$ltfv_ratio, method = opt$method, dlevel = 0)
Sie können nach Belieben mit errorDump.rda
in eine interaktive R-Sitzung laden load('~/path/to/errorDump.rda')
. Rufen Sie debugger(errorDump)
nach dem Laden auf, um alle R-Objekte im Speicher in einer der aktiven Umgebungen zu durchsuchen. debugger()
Weitere Informationen finden Sie in der R-Hilfe .
Dieser Workflow ist enorm hilfreich, wenn Sie R in einer Produktionsumgebung ausführen, in der nicht interaktive R-Sitzungen über die Befehlszeile initiiert werden und Informationen über unerwartete Fehler beibehalten werden sollen. Die Möglichkeit, Speicher in eine Datei zu kopieren, mit der Sie den Arbeitsspeicher zum Zeitpunkt des Fehlers überprüfen können, sowie die Zeilennummern des Fehlers im Aufrufstapel ermöglichen ein schnelles Post-Mortem-Debugging der Fehlerursache.