Визначення глобального варіанту R для обробки некатастрофічних помилок працювало для мене, а також налаштований робочий процес для збереження інформації про помилку та вивчення цієї інформації після відмови. На даний момент я використовую R версії 3.4.1. Нижче я включив опис робочого процесу, який працював на мене, а також деякий код, який я використовував для встановлення глобальної опції обробки помилок у Р.
Як я налаштував, обробка помилок також створює файл RData, що містить усі об'єкти в робочій пам'яті на момент помилки. Цей дамп можна зчитувати назад у R за допомогою, load()
а потім різні середовища, які вони існували на момент помилки, можна інтерактивно перевіряти, використовуючи debugger(errorDump)
.
Зауважу, що мені вдалося отримати номери рядків у traceback()
висновку з будь-яких спеціальних функцій всередині стека, але лише в тому випадку, якщо я використовував цю keep.source=TRUE
опцію під час виклику source()
будь-яких спеціальних функцій, що використовуються в моєму сценарії. Без цієї опції, встановивши параметр глобальної обробки помилок, як traceback()
показано нижче, надійшов повний вихід журналу помилок з назвою error.log
, але номери рядків були недоступні.
Ось загальні кроки, які я здійснив у своєму робочому процесі, і як мені вдалося отримати доступ до дампа пам’яті та журналу помилок після неінтерактивної помилки R.
Я ставлю наступне у верхній частині основного сценарію, який я дзвонив з командного рядка. Це встановлює опцію глобальної обробки помилок для сеансу R. Називався мій головний сценарій myMainScript.R
. У різних рядках коду є коментарі після них, що описують, що вони роблять. В основному, при такому варіанті, коли R зіткнеться з помилкою, яка викликає помилку stop()
, він створить файл дамп RData (* .rda) робочої пам’яті у всіх активних середовищах у каталозі, ~/myUsername/directoryForDump
а також запише журнал помилок, названий error.log
з деякою корисною інформацією в той самий каталог. Ви можете модифікувати цей фрагмент, щоб додати іншу обробку помилок (наприклад, додати часову позначку до дамп-файлу та назви файлів журналу помилок тощо).
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()}))
Переконайтеся, що параметр із головного сценарію та наступних викликів функцій у будь-який момент, коли функція отримується, використовується параметр keep.source=TRUE
. Тобто для джерела функції ви б використовували source('~/path/to/myFunction.R', keep.source=TRUE)
. Це потрібно, щоб traceback()
вихід містив номери рядків. Схоже, ви також можете встановити цю опцію в усьому світі options( keep.source=TRUE )
, але я не перевіряв це, чи працює він. Якщо вам не потрібні номери рядків, цю опцію можна пропустити.
- З терміналу (за межами R) викликайте головний скрипт у пакетному режимі, використовуючи
Rscript myMainScript.R
. Це запускає новий неінтерактивний сеанс R та запускає сценарій myMainScript.R
. Фрагмент коду, наведений на кроці 1, розміщений у верхній частині, myMainScript.R
встановлює параметр обробки помилок для неінтерактивного сеансу R.
- Зустрічайте помилку десь у межах виконання
myMainScript.R
. Це може бути в самому головному сценарії або вкладене в кілька функцій. При виявленні помилки обробка буде виконуватися, як зазначено в кроці 1, і сеанс R припиняється.
- Файл дамп RData з іменем
errorDump.rda
та журнал помилок з назвою error.log
створюються в каталозі, визначеному '~/myUsername/directoryForDump'
в налаштуваннях глобальної обробки помилок.
У вільний час error.log
перегляньте інформацію про помилку, включаючи саме повідомлення про помилку та повний слід стека, що призводить до помилки. Ось приклад журналу, який генерується помилково; відзначте цифри після #
символу - це рядкові помилки в різних точках стеку викликів:
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)
У вільний час ви можете завантажитися errorDump.rda
в інтерактивну сесію R, використовуючи load('~/path/to/errorDump.rda')
. Після завантаження зателефонуйте debugger(errorDump)
для перегляду всіх об'єктів R у пам'яті в будь-якому з активних середовищ. Для debugger()
отримання додаткової інформації див. Довідку R.
Цей робочий процес надзвичайно корисний при запуску R у певному виробничому середовищі, де у командному рядку починаються неінтерактивні сеанси R, і ви хочете, щоб інформація зберігалася про несподівані помилки. Можливість скидання пам’яті у файл, який ви можете використовувати для перевірки робочої пам’яті під час помилки, а також номери рядків помилки в стеці виклику, сприяють швидкому післясмертовому налагодженню того, що спричинило помилку.