R tryCatch() - ссылка на возврат expr() в finally?

Я пытаюсь написать функцию для обработки выполнения пакетных заданий, регистрации ошибок и статистики результатов задания.

Есть ли способ сослаться на возвращаемое значение блока expr из блока finally?

my_do <- function(FUN, ...){

  result <- tryCatch({
      FUN(...)
    }, 
    error = function(e) {
      message("error.")
    },
    finaly = {

      # how can I reference the returning value of FUN(...) in finally block?
      # so for example, I can write code like this:

      message(paste("Result dimensions:", dim(expr_result)))
    },
  )

  return(result)
}

person taiyodayo    schedule 30.07.2020    source источник
comment
Если FUN(...) выдает ошибку, из нее нет возвращаемого значения. Я думаю, вас могут заинтересовать перезапуски, но ваш пример не является ни полным/воспроизводимым, ни достаточно конкретным.   -  person Roland    schedule 30.07.2020
comment
Спасибо за комментарий, Роланд, да, когда я пытался минимизировать свой исходный код, я пропустил несколько битов, что делает вопрос немного расплывчатым. изначально мой код имел механизм безопасности для возврата альтернативного фрейма данных в случае ошибки.   -  person taiyodayo    schedule 31.07.2020


Ответы (2)


Если возвращаемое значение tryCatch сохраняется в переменной, например

x <- tryCatch({ 1; }, finally = { message("value is ", x); })
# Error in message("value is ", x) : object 'x' not found

тогда ответ нет, поскольку объект x не существует, когда tryCatch выполняет finally=.

Однако блок кода работает в родительской среде, поэтому вы можете сделать это вместо этого:

tryCatch({ x <- 1; }, finally = { message("value is ", x); })
# value is 1
x
# [1] 1

Это зависит от того, что возвращаемое значение устанавливается без ошибок. Если где-то в выполнении есть ошибка, то... очевидно, не будет никакого значения для извлечения.

person r2evans    schedule 30.07.2020
comment
Спасибо, Эванс, за разъяснение, что без сохранения результата в объект я не могу ссылаться на вывод из блока expr! Я ошибочно предположил, что может быть способ каким-то образом сослаться на возврат блока expr. Я изменил свой исходный код в соответствии с вашим предложением, чтобы он работал так, как я хотел. Надеюсь, у вас замечательный день! - person taiyodayo; 31.07.2020

Я предполагаю, что это не лучший способ использования finally.

Существуют следующие рекомендации по использованию finally (http://adv-r.had.co.nz/Exceptions-Debugging.html):

Он определяет блок кода (не функцию), который должен выполняться независимо от того, успешно или нет выполнено начальное выражение. Это может быть полезно для очистки (например, удаление файлов, закрытие подключений). Функционально это эквивалентно использованию on.exit(), но может содержать меньшие фрагменты кода, чем целая функция.

person codez0mb1e    schedule 30.07.2020
comment
Спасибо, что указали мне на блестящие статьи Хэдли! будем читать дальше там. - person taiyodayo; 31.07.2020