0Pricing
R Academy · Урок

tryCatch() для восстановления после ошибок

Перехватывайте и обрабатывайте ошибки, предупреждения и сообщения с помощью tryCatch().

«tryCatch() для восстановления после ошибок» — бесплатный урок R Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения R Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс R Academy содержит 4 уроков всего.

Что такое tryCatch()?

tryCatch() позволяет выполнить выражение и перехватить любые создаваемые им условия (ошибки, предупреждения и сообщения). Если выражение выполняется успешно, возвращается его значение. Если оно создаёт условие, вместо него вызывается соответствующий обработчик.

result <- tryCatch({
  sqrt(16)
}, error = function(e) {
  NA
})
cat('Result:', result, '\n')

Перехват ошибки

Когда выражение внутри tryCatch() вызывает stop(), выполнение переходит к обработчику error. Обработчик получает объект условия и возвращает его значение как результат всего вызова tryCatch().

safe_divide <- function(x, y) {
  tryCatch({
    if (y == 0) stop('division by zero')
    x / y
  }, error = function(e) {
    cat('Caught error:', conditionMessage(e), '\n')
    NA
  })
}
cat(safe_divide(10, 2), '\n')
cat(safe_divide(10, 0), '\n')

Перехват предупреждения

Обработчик warning работает так же, как обработчик error, но перехватывает условия предупреждений. Обратите внимание: если в tryCatch() определён обработчик warning, предупреждения вызывают нелокальный выход, как и ошибки, поэтому выполнение не продолжается после предупреждения.

result <- tryCatch({
  log(-1)
}, warning = function(w) {
  cat('Warning caught:', conditionMessage(w), '\n')
  -999
})
cat('Result:', result, '\n')

Перехват сообщения

Вы также можете перехватывать условия message(). Это позволяет перехватывать и изменять информационный вывод функций, которыми Вы не управляете. Обработчик получает объект условия, а текст сообщения содержит завершающий перевод строки.

result <- tryCatch({
  message('Loading data...')
  42
}, message = function(m) {
  cat('Intercepted message:', trimws(conditionMessage(m)), '\n')
  -1
})
cat('Result:', result, '\n')

Блок finally

Блок finally всегда выполняется после выражения — независимо от того, завершилось ли оно успешно, с ошибкой или с предупреждением. Используйте его для очистки, например для закрытия соединений, сброса параметров или записи сообщения о завершении.

result <- tryCatch({
  cat('Trying...\n')
  stop('oops')
}, error = function(e) {
  cat('Handled:', e$message, '\n')
  -1
}, finally = {
  cat('Finally block always runs\n')
})
cat('Result:', result, '\n')

Несколько обработчиков

В одном вызове tryCatch() можно задать обработчики для нескольких типов условий. R выбирает первый подходящий обработчик. Если определены обработчики для error и warning, предупреждения перехватываются до того, как они могут превратиться в ошибки.

handle_it <- function(expr_result) {
  tryCatch(expr_result,
    error   = function(e) paste('ERROR:', e$message),
    warning = function(w) paste('WARN:', w$message),
    message = function(m) paste('MSG:', trimws(m$message))
  )
}
cat(handle_it(stop('bad input')), '\n')
cat(handle_it(log(-1)), '\n')

Восстановление после ошибки в цикле

Очень практичный шаблон: оберните тело цикла в tryCatch(), чтобы одна неудачная итерация не останавливала весь цикл. Это особенно важно при обработке файлов, вызовов API или пользовательских входных данных, которые могут непредсказуемо завершаться с ошибкой.

inputs <- list(4, -1, 0, 16, 'x')
results <- vector('list', length(inputs))
for (i in seq_along(inputs)) {
  results[[i]] <- tryCatch(
    sqrt(as.numeric(inputs[[i]])),
    warning = function(w) NA,
    error   = function(e) NA
  )
}
cat('Results:', unlist(results), '\n')

Возврат осмысленных значений по умолчанию при ошибке

Удобный шаблон — возвращать разумное значение по умолчанию из обработчика ошибки. Возвращаемое обработчиком значение становится результатом tryCatch(). Хорошо подходят NA, NULL, 0 или список со значениями по умолчанию.

safe_parse <- function(x) {
  tryCatch(
    as.numeric(x),
    warning = function(w) {
      cat('Cannot parse:', x, '-> using 0\n')
      0
    }
  )
}
cat(safe_parse('3.14'), '\n')
cat(safe_parse('abc'), '\n')
cat(safe_parse('99'), '\n')

Извлечение сообщения об ошибке

В обработчике ошибки используйте conditionMessage(e) или сокращённую запись e$message, чтобы получить текст ошибки. Используйте conditionCall(e) или e$call, чтобы получить вызов, который её вызвал.

tryCatch(
  stop('file not found: data.csv'),
  error = function(e) {
    cat('Message:', conditionMessage(e), '\n')
    cat('Class  :', paste(class(e), collapse=', '), '\n')
  }
)

tryCatch() и try()

В R также есть более простая функция try(expr). При ошибке она возвращает объект класса 'try-error' вместо остановки выполнения. Используйте try() для быстрых однострочных выражений, а tryCatch() — когда нужен полный контроль над обработчиками или блок finally.

# try() returns try-error object on failure
result <- try(log('x'), silent = TRUE)
if (inherits(result, 'try-error')) {
  cat('try() caught error\n')
} else {
  cat('Result:', result, '\n')
}

Вложенные вызовы tryCatch()

Вызовы tryCatch() можно вкладывать друг в друга. Внутренний tryCatch() первым перехватывает условия; если он повторно выдаёт условие (с помощью stop(e)), внешний обработчик перехватывает повторно выданное условие.

outer_result <- tryCatch({
  tryCatch({
    stop('inner error')
  }, error = function(e) {
    cat('Inner handler, re-throwing\n')
    stop(paste('Wrapped:', e$message))
  })
}, error = function(e) {
  cat('Outer handler:', e$message, '\n')
  'recovered'
})
cat('Final:', outer_result, '\n')

Быстрая проверка

В tryCatch() какой блок всегда выполняется независимо от того, произошла ошибка или нет?

tryCatch(): главное

Главное о tryCatch():

  • Перехватывайте ошибки с помощью error = function(e) {...}, а предупреждения — с помощью warning = function(w) {...}
  • Возвращаемое обработчиком значение становится результатом tryCatch()
  • finally выполняется всегда — это удобно для очистки
  • Оберните тела циклов в tryCatch() для надёжной обработки ненадёжных входных данных
  • e$message или conditionMessage(e) извлекает текст ошибки
  • try(expr, silent=TRUE) — более простой однострочный вариант
safe_op <- function(x) {
  tryCatch({
    if (!is.numeric(x)) stop('not numeric')
    sqrt(x)
  }, error = function(e) {
    cat('Error:', e$message, '\n')
    NA
  }, finally = {
    cat('Done processing', x, '\n')
  })
}
cat(safe_op(9), '\n')
cat(safe_op('a'), '\n')

Часто задаваемые вопросы

Урок «tryCatch() для восстановления после ошибок» бесплатный?

Да — полный текст урока «tryCatch() для восстановления после ошибок» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс R Academy, подпишись на CoddyKit PRO. Курс R Academy содержит 4 уроков всего.

Чему я научусь в уроке «tryCatch() для восстановления после ошибок»?

Перехватывайте и обрабатывайте ошибки, предупреждения и сообщения с помощью tryCatch(). Ты практикуешь R Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать R Academy?

Предыдущий опыт не требуется. R Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «tryCatch() для восстановления после ошибок»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке R Academy?

Да. Каждый урок R Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Ошибки, предупреждения и сообщения в R
  2. tryCatch() для восстановления после ошибок
  3. withCallingHandlers() и перезапуски
  4. Надёжные функции с stop() и warning()
← Назад к R Academy