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 — локальная установка не требуется.
Все уроки этого курса
- Ошибки, предупреждения и сообщения в R
- tryCatch() для восстановления после ошибок
- withCallingHandlers() и перезапуски
- Надёжные функции с stop() и warning()