Especificar a opção R global para lidar com erros não catastróficos funcionou para mim, junto com um fluxo de trabalho personalizado para reter informações sobre o erro e examinar essas informações após a falha. Atualmente, estou executando o R versão 3.4.1. Abaixo, incluí uma descrição do fluxo de trabalho que funcionou para mim, bem como alguns códigos que usei para definir a opção de tratamento de erros global em R.
Como eu configurei, o tratamento de erros também cria um arquivo RData contendo todos os objetos na memória de trabalho no momento do erro. Esse dump pode ser lido de volta em R usando load()
e, em seguida, os vários ambientes que existiam no momento do erro podem ser inspecionados interativamente usando debugger(errorDump)
.
Observarei que consegui obter números de linha na traceback()
saída de quaisquer funções personalizadas dentro da pilha, mas apenas se usasse a keep.source=TRUE
opção ao chamar source()
qualquer função personalizada usada em meu script. Sem essa opção, definir a opção de tratamento de erros global conforme abaixo envia a saída completa de traceback()
para um log de erros denominado error.log
, mas os números de linha não estão disponíveis.
Estas são as etapas gerais que executei em meu fluxo de trabalho e como consegui acessar o despejo de memória e o log de erros após uma falha R não interativa.
Coloquei o seguinte no topo do script principal que estava chamando da linha de comando. Isso define a opção de tratamento de erros global para a sessão R. Meu script principal foi chamado myMainScript.R
. As várias linhas do código têm comentários após elas descrevendo o que fazem. Basicamente, com esta opção, quando R encontra um erro que dispara stop()
, ele criará um arquivo de despejo RData (* .rda) da memória de trabalho em todos os ambientes ativos no diretório ~/myUsername/directoryForDump
e também escreverá um log de erro nomeado error.log
com algumas informações úteis para o mesmo diretório. Você pode modificar este trecho para adicionar outro tratamento em caso de erro (por exemplo, adicionar um carimbo de data / hora ao arquivo de despejo e nomes de arquivo de log de erro, 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()}))
Certifique-se de que a partir do script principal e de quaisquer chamadas de função subsequentes, sempre que uma função for originada, a opção keep.source=TRUE
seja usada. Ou seja, para obter uma função, você usaria source('~/path/to/myFunction.R', keep.source=TRUE)
. Isso é necessário para que a traceback()
saída contenha números de linha. Parece que você também pode definir essa opção globalmente usando options( keep.source=TRUE )
, mas não testei isso para ver se funciona. Se você não precisa de números de linha, pode omitir esta opção.
- Do terminal (fora de R), chame o script principal no modo batch usando
Rscript myMainScript.R
. Isso inicia uma nova sessão R não interativa e executa o script myMainScript.R
. O fragmento de código fornecido na etapa 1 que foi colocado na parte superior de myMainScript.R
configura a opção de tratamento de erros para a sessão R não interativa.
- Encontrou um erro em algum lugar durante a execução de
myMainScript.R
. Isso pode estar no próprio script principal ou em várias funções aninhadas profundamente. Quando o erro for encontrado, o tratamento será executado conforme especificado na etapa 1 e a sessão R será encerrada.
- Um arquivo de despejo RData denominado ee um
errorDump.rda
log de erro denominado error.log
são criados no diretório especificado por '~/myUsername/directoryForDump'
na configuração da opção de tratamento de erros global.
No seu lazer, inspecione error.log
para revisar as informações sobre o erro, incluindo a própria mensagem de erro e o rastreamento de pilha completo que levou ao erro. Aqui está um exemplo do log gerado em caso de erro; observe que os números após o #
caractere são os números da linha do erro em vários pontos da pilha de chamadas:
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)
Em seu lazer, você pode carregar errorDump.rda
em uma sessão R interativa usando load('~/path/to/errorDump.rda')
. Uma vez carregado, chame debugger(errorDump)
para navegar todos os objetos R na memória em qualquer um dos ambientes ativos. Consulte a ajuda do R debugger()
para obter mais informações.
Esse fluxo de trabalho é extremamente útil ao executar o R em algum tipo de ambiente de produção onde você tem sessões R não interativas sendo iniciadas na linha de comando e deseja que as informações sejam retidas sobre erros inesperados. A capacidade de despejar memória em um arquivo que você pode usar para inspecionar a memória de trabalho no momento do erro, junto com os números de linha do erro na pilha de chamadas, facilita a depuração post-mortem rápida do que causou o erro.