withCallingHandlers()와 재시작
비지역 조건 처리를 위해 withCallingHandlers()를 사용합니다.
withCallingHandlers()와 재시작은(는) CoddyKit의 무료 R Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 R Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
tryCatch와 withCallingHandlers 비교
핵심 차이는 다음과 같습니다. tryCatch()는 비지역적 종료를 설정하므로 조건이 포착되면 제어가 표현식 밖으로 이동하고 돌아오지 않습니다. withCallingHandlers()는 호출 스택을 그대로 유지하며 처리 후 실행을 재개할 수 있습니다.
# tryCatch: execution does NOT continue after warning
tryCatch({
warning('first')
cat('This line is never reached\n')
}, warning = function(w) cat('tryCatch caught:', w$message, '\n'))withCallingHandlers는 실행을 유지함
withCallingHandlers()를 사용하면 처리기가 실행되지만 조건이 신호를 보낸 후에도 실행이 계속됩니다. 단, 처리기 자체가 오류를 발생시키거나 재시작을 호출하는 경우는 예외입니다. 호출 스택은 풀리지 않습니다.
withCallingHandlers({
warning('first warning')
cat('Execution continues here\n')
warning('second warning')
cat('And here too\n')
}, warning = function(w) {
cat('Handler saw:', w$message, '\n')
invokeRestart('muffleWarning')
})muffleWarning 재시작
경고 처리기 내부에서 invokeRestart('muffleWarning')을 호출하면 R의 기본 처리기가 경고를 출력하지 않도록 억제할 수 있습니다. 이를 사용하지 않으면 처리기가 실행된 후에도 R이 기본 메커니즘을 통해 경고를 출력합니다.
# Without muffleWarning: warning still shows after handler
withCallingHandlers({
warning('test')
}, warning = function(w) {
cat('Handler ran\n')
# no muffleWarning: default handler still fires
})muffleMessage 재시작
마찬가지로 메시지 처리기 내부에서 invokeRestart('muffleMessage')를 호출하면 사용자 지정 처리기가 메시지를 처리한 후 해당 메시지를 표시하지 않게 할 수 있습니다. suppressMessages()는 이 메커니즘을 사용합니다.
withCallingHandlers({
message('Progress: 50%')
message('Progress: 100%')
}, message = function(m) {
cat('[LOG]', trimws(m$message), '\n')
invokeRestart('muffleMessage')
})중단 없이 경고 기록하기
withCallingHandlers()의 실용적인 용도는 코드가 끝까지 실행되도록 하면서 경고를 로그 벡터에 수집하는 것입니다. tryCatch()는 첫 번째 경고에서 중단하지만 withCallingHandlers()는 모든 경고를 수집합니다.
warnings_log <- character(0)
result <- withCallingHandlers({
x <- log(-1)
y <- sqrt(-4)
c(x, y)
}, warning = function(w) {
warnings_log <<- c(warnings_log, w$message)
invokeRestart('muffleWarning')
})
cat('Warnings logged:', length(warnings_log), '\n')
cat(warnings_log, sep = '\n')invokeRestart() 개념
재시작은 조건을 신호로 알리는 코드가 제공할 수 있는 미리 정의된 복구 전략입니다. invokeRestart(name)은 이러한 전략 중 하나를 선택합니다. 기본 제공 재시작에는 'muffleWarning'과 'muffleMessage'가 있으며, withRestarts()로 사용자 지정 재시작을 정의할 수 있습니다.
# withRestarts() offers named recovery options
divide_safe <- function(x, y) {
withRestarts(
{
if (y == 0) stop('division by zero')
x / y
},
use_zero = function() 0,
use_na = function() NA
)
}
# A handler can pick a restart
withCallingHandlers(
divide_safe(10, 0),
error = function(e) invokeRestart('use_zero')
)withCallingHandlers와 tryCatch 결합
두 가지를 중첩할 수 있습니다. 바깥쪽에 withCallingHandlers()를 사용해 조건을 기록하거나 개수를 세고, 안쪽에 tryCatch()를 사용해 대체값을 제공하십시오. 바깥 처리기가 조건을 먼저 확인합니다.
n_warnings <- 0L
result <- withCallingHandlers(
tryCatch(log(-1), warning = function(w) -999),
warning = function(w) {
n_warnings <<- n_warnings + 1L
cat('Logged warning #', n_warnings, '\n')
}
)
cat('Result:', result, '\n')사용자 지정 조건 클래스
클래스가 c('myError', 'error', 'condition')인 목록에 structure()를 호출하면 사용자 지정 조건 클래스를 만들 수 있습니다. 처리기는 클래스를 기준으로 일치하므로 사용자 지정 클래스를 사용하면 모든 오류를 포착하지 않고 특정 오류 유형만 포착할 수 있습니다.
my_error <- function(msg, data = NULL) {
structure(
class = c('my_error', 'error', 'condition'),
list(message = msg, data = data)
)
}
tryCatch(
stop(my_error('custom error', data = 42)),
my_error = function(e) cat('Custom handler, data=', e$data, '\n'),
error = function(e) cat('Generic handler\n')
)withCallingHandlers를 사용할 때
실행을 중단하지 않고 조건을 관찰하거나 기록하려면 withCallingHandlers()를 사용하십시오. 조건에서 복구하여 대체값을 반환하려면 tryCatch()를 사용하십시오. 두 함수는 서로 다른 문제를 해결합니다.
# withCallingHandlers: observe all, continue
withCallingHandlers(
for (x in c(4, -1, 9, -4)) cat(suppressWarnings(sqrt(x)), ''),
warning = function(w) cat('[warn]', '')
)
cat('\n')조건 신호 전달 과정
조건에 신호가 전달되면 R은 처리기를 찾기 위해 호출 스택을 따라 위로 올라갑니다. withCallingHandlers() 처리기는 동적 컨텍스트에서 실행되므로 호출 스택이 유지됩니다. tryCatch() 처리기는 스택이 풀린 후 실행되므로 원래 컨텍스트가 사라집니다.
# Demonstrate: withCallingHandlers handler can see full stack
f <- function() {
withCallingHandlers(
g(),
warning = function(w) {
cat('Caught in f, stack length:', sys.nframe(), '\n')
invokeRestart('muffleWarning')
}
)
}
g <- function() warning('from g')
f()suppressWarnings() 구현
suppressWarnings(expr)는 본질적으로 withCallingHandlers(expr, warning = function(w) invokeRestart('muffleWarning'))입니다. 이를 이해하면 특정 경고 유형만 억제하는 자체 변형을 만들 수 있습니다.
# Suppress only NaN warnings, not others
suppress_nan_warn <- function(expr) {
withCallingHandlers(expr, warning = function(w) {
if (grepl('NaN', conditionMessage(w)))
invokeRestart('muffleWarning')
})
}
suppress_nan_warn(log(-1)) # NaN warning suppressed
tryCatch(
suppress_nan_warn(warning('other issue')),
warning = function(w) cat('Other warning kept:', w$message, '\n')
)빠른 확인
withCallingHandlers()와 tryCatch()의 주요 차이점은 무엇입니까?
재시작: 핵심 정리
withCallingHandlers와 재시작의 핵심 정리:
withCallingHandlers()= 지역 처리기, 호출 스택 유지, 실행 계속 가능tryCatch()= 비지역적 종료, 스택이 풀림, 대체값 반환 가능invokeRestart('muffleWarning')은 경고의 기본 출력을 억제합니다.invokeRestart('muffleMessage')는 메시지의 기본 출력을 억제합니다.- 중단 없이 모든 조건을 수집하거나 기록하려면
withCallingHandlers()를 사용하십시오. - 사용자 지정 조건 클래스를 사용하면 특정 오류 유형만 선택적으로 포착할 수 있습니다.
log_vec <- character(0)
withCallingHandlers({
message('start')
warning('low memory')
message('end')
}, message = function(m) {
log_vec <<- c(log_vec, paste('MSG:', trimws(m$message)))
invokeRestart('muffleMessage')
}, warning = function(w) {
log_vec <<- c(log_vec, paste('WARN:', w$message))
invokeRestart('muffleWarning')
})
cat(log_vec, sep = '\n')자주 묻는 질문
“withCallingHandlers()와 재시작” 강의는 무료인가요?
네 — “withCallingHandlers()와 재시작” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 R Academy 강의 전체를 잠금 해제할 수 있습니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“withCallingHandlers()와 재시작”에서 뭘 배우나요?
비지역 조건 처리를 위해 withCallingHandlers()를 사용합니다. 브라우저에서 직접 실행하는 실습 코드로 R Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
R Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 R Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“withCallingHandlers()와 재시작” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 R Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 R Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- R의 오류, 경고, 메시지
- 오류 복구를 위한 tryCatch()
- withCallingHandlers()와 재시작
- stop()과 warning()으로 견고한 함수 작성하기