Especificar la opción R global para manejar errores no catastróficos funcionó para mí, junto con un flujo de trabajo personalizado para retener información sobre el error y examinar esta información después de la falla. Actualmente estoy ejecutando R versión 3.4.1. A continuación, incluí una descripción del flujo de trabajo que me funcionó, así como un código que usé para configurar la opción de manejo de errores global en R.
Como lo tengo configurado, el manejo de errores también crea un archivo RData que contiene todos los objetos en la memoria de trabajo en el momento del error. Este volcado se puede leer de nuevo en R usando load()y luego los diversos entornos tal como existían en el momento del error se pueden inspeccionar de forma interactiva usando debugger(errorDump).
Notaré que pude obtener números de línea en la traceback()salida de cualquier función personalizada dentro de la pila, pero solo si usé la keep.source=TRUEopción al llamar source()a las funciones personalizadas utilizadas en mi script. Sin esta opción, la configuración de la opción de manejo de errores globales como se muestra a continuación envió la salida completa de traceback()a un registro de errores llamado error.log, pero los números de línea no estaban disponibles.
Estos son los pasos generales que tomé en mi flujo de trabajo y cómo pude acceder al volcado de memoria y al registro de errores después de una falla de R no interactiva.
Puse lo siguiente en la parte superior del script principal al que estaba llamando desde la línea de comandos. Esto establece la opción de manejo de errores global para la sesión R. Mi guión principal se llamó myMainScript.R. Las diversas líneas del código tienen comentarios después de ellas que describen lo que hacen. Básicamente, con esta opción, cuando R encuentra un error que se activa stop(), creará un archivo de volcado RData (* .rda) de la memoria de trabajo en todos los entornos activos en el directorio ~/myUsername/directoryForDumpy también escribirá un registro de errores error.logcon información útil para el mismo directorio. Puede modificar este fragmento para agregar otro manejo en caso de error (por ejemplo, agregar una marca de tiempo al archivo de volcado y nombres de archivo de registro de errores, etc.).
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()}))
Asegúrese de que desde el script principal y cualquier llamada de función subsiguiente, siempre que se obtenga una función, keep.source=TRUEse utilice la opción . Es decir, para obtener una función, usaría source('~/path/to/myFunction.R', keep.source=TRUE). Esto es necesario para que la traceback()salida contenga números de línea. Parece que también puede configurar esta opción globalmente usando options( keep.source=TRUE ), pero no lo he probado para ver si funciona. Si no necesita números de línea, puede omitir esta opción.
- Desde el terminal (fuera de R), llame al script principal en modo por lotes usando
Rscript myMainScript.R. Esto inicia una nueva sesión de R no interactiva y ejecuta el script myMainScript.R. El fragmento de código proporcionado en el paso 1 que se colocó en la parte superior de myMainScript.Restablece la opción de manejo de errores para la sesión R no interactiva.
- Encuentra un error en algún lugar de la ejecución de
myMainScript.R. Esto puede estar en el propio script principal o anidar varias funciones en profundidad. Cuando se encuentra el error, el manejo se realizará como se especifica en el paso 1 y la sesión de R terminará.
- Se crea un archivo de volcado RData denominado
errorDump.rday un registro de errores denominado error.logen el directorio especificado por '~/myUsername/directoryForDump'en la configuración de la opción de manejo de errores globales.
En su tiempo libre, inspeccione error.logpara revisar la información sobre el error, incluido el mensaje de error y el seguimiento de la pila completa que condujo al error. Aquí hay un ejemplo del registro que se genera en caso de error; tenga en cuenta que los números después del #carácter son los números de línea del error en varios puntos de la pila de llamadas:
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)
En su tiempo libre, puede cargar errorDump.rdaen una sesión R interactiva usando load('~/path/to/errorDump.rda'). Una vez cargado, llame debugger(errorDump)para examinar todos los objetos R en la memoria en cualquiera de los entornos activos. Consulte la ayuda de R debugger()para obtener más información.
Este flujo de trabajo es enormemente útil cuando se ejecuta R en algún tipo de entorno de producción en el que se inician sesiones de R no interactivas en la línea de comandos y desea que se conserve información sobre errores inesperados. La capacidad de volcar la memoria en un archivo que puede usar para inspeccionar la memoria de trabajo en el momento del error, junto con tener los números de línea del error en la pila de llamadas, facilita la depuración post mortem rápida de lo que causó el error.