withCallingHandlers() und Restarts
Verwenden Sie withCallingHandlers() zur Behandlung nichtlokaler Bedingungen.
withCallingHandlers() und Restarts ist eine kostenlose R Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des R Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der R Academy-Kurs umfasst insgesamt 4 Lektionen.
tryCatch im Vergleich zu withCallingHandlers
Der entscheidende Unterschied: tryCatch() führt zu einem nicht-lokalen Abbruch – sobald eine Bedingung abgefangen wurde, wird die Kontrolle aus dem Ausdruck heraus übertragen und kehrt nicht zurück. withCallingHandlers() erhält den Aufrufstapel und kann die Ausführung nach der Behandlung fortsetzen.
# 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 setzt die Ausführung fort
Bei withCallingHandlers() wird der Handler ausgeführt, aber die Ausführung wird nach dem Signalisieren der Bedingung fortgesetzt, sofern der Handler nicht selbst einen Fehler auslöst oder einen Restart aufruft. Der Aufrufstapel wird nicht abgewickelt.
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')
})Der Restart muffleWarning
Wenn Sie innerhalb eines Warnungs-Handlers invokeRestart('muffleWarning') aufrufen, unterdrücken Sie die Ausgabe der Warnung durch R's Standard-Handler. Ohne diesen Aufruf würde R die Warnung nach der Ausführung Ihres Handlers weiterhin über seine Standardmechanismen ausgeben.
# Without muffleWarning: warning still shows after handler
withCallingHandlers({
warning('test')
}, warning = function(w) {
cat('Handler ran\n')
# no muffleWarning: default handler still fires
})Der Restart muffleMessage
Entsprechend unterdrückt invokeRestart('muffleMessage') innerhalb eines Nachrichten-Handlers die Nachricht, nachdem Ihr eigener Handler sie verarbeitet hat. Auf diesem Mechanismus basiert suppressMessages().
withCallingHandlers({
message('Progress: 50%')
message('Progress: 100%')
}, message = function(m) {
cat('[LOG]', trimws(m$message), '\n')
invokeRestart('muffleMessage')
})Warnungen protokollieren, ohne die Ausführung zu stoppen
Eine praktische Verwendung von withCallingHandlers(): Sammeln Sie Warnungen in einem Protokollvektor, während der Code vollständig ausgeführt wird. tryCatch() würde bei der ersten Warnung anhalten; withCallingHandlers() sammelt sie alle.
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')Das Konzept von invokeRestart()
Restarts sind vordefinierte Strategien zur Fehlerbehebung, die der Code anbieten kann, der die Bedingung signalisiert. invokeRestart(name) wählt eine dieser Strategien aus. Zu den integrierten Restarts gehören 'muffleWarning' und 'muffleMessage'; mit withRestarts() können Sie eigene definieren.
# 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 und tryCatch kombinieren
Sie können beide verschachteln: Verwenden Sie außen withCallingHandlers(), um Bedingungen zu protokollieren oder zu zählen, und innen tryCatch(), um einen Ersatzwert bereitzustellen. Der äußere Handler sieht die Bedingung zuerst.
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')Benutzerdefinierte Bedingungsklassen
Sie können benutzerdefinierte Bedingungsklassen erstellen, indem Sie structure() auf eine Liste mit der Klasse c('myError', 'error', 'condition') anwenden. Handler stimmen anhand der Klasse überein. Benutzerdefinierte Klassen ermöglichen es Ihnen daher, bestimmte Fehlertypen abzufangen, ohne alle Fehler abzufangen.
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')
)Wann Sie withCallingHandlers verwenden sollten
Verwenden Sie withCallingHandlers(), wenn Sie Bedingungen beobachten oder protokollieren möchten, ohne die Ausführung anzuhalten. Verwenden Sie tryCatch(), wenn Sie eine Bedingung behandeln und einen alternativen Wert zurückgeben möchten. Beide lösen unterschiedliche Probleme.
# withCallingHandlers: observe all, continue
withCallingHandlers(
for (x in c(4, -1, 9, -4)) cat(suppressWarnings(sqrt(x)), ''),
warning = function(w) cat('[warn]', '')
)
cat('\n')Die Kette der Bedingungssignalisierung
Wenn eine Bedingung signalisiert wird, durchsucht R den Aufrufstapel nach Handlern. Handler von withCallingHandlers() werden im dynamischen Kontext ausgeführt, wobei der Aufrufstapel erhalten bleibt. Handler von tryCatch() werden nach dem Abwickeln des Stapels ausgeführt – der ursprüngliche Kontext ist dann nicht mehr vorhanden.
# 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()Implementierung von suppressWarnings()
suppressWarnings(expr) entspricht im Wesentlichen withCallingHandlers(expr, warning = function(w) invokeRestart('muffleWarning')). Wenn Sie dies verstehen, können Sie eigene Varianten erstellen, die nur bestimmte Warnungstypen unterdrücken.
# 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')
)Kurze Überprüfung
Was ist der wichtigste Unterschied zwischen withCallingHandlers() und tryCatch()?
Restarts: Wichtigste Erkenntnisse
Wichtigste Erkenntnisse zu withCallingHandlers und Restarts:
withCallingHandlers()= lokaler Handler, Aufrufstapel bleibt erhalten, Ausführung kann fortgesetzt werdentryCatch()= nicht-lokaler Abbruch, Stapel wird abgewickelt, alternativer Wert kann zurückgegeben werdeninvokeRestart('muffleWarning')unterdrückt die standardmäßige Ausgabe der WarnunginvokeRestart('muffleMessage')unterdrückt die standardmäßige Ausgabe der Nachricht- Verwenden Sie
withCallingHandlers(), um alle Bedingungen zu sammeln oder zu protokollieren, ohne die Ausführung anzuhalten - Benutzerdefinierte Bedingungsklassen ermöglichen das gezielte Abfangen bestimmter Fehlertypen
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')Häufig gestellte Fragen
Ist die Lektion „withCallingHandlers() und Restarts“ kostenlos?
Ja — der vollständige Text von „withCallingHandlers() und Restarts“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des R Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der R Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „withCallingHandlers() und Restarts“?
Verwenden Sie withCallingHandlers() zur Behandlung nichtlokaler Bedingungen. Du übst R Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um R Academy zu starten?
Keine Vorkenntnisse erforderlich. R Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „withCallingHandlers() und Restarts“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser R Academy-Lektion Code schreiben und ausführen?
Ja. Jede R Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Fehler, Warnungen und Meldungen in R
- Fehlerbehandlung mit tryCatch()
- withCallingHandlers() und Restarts
- Robuste Funktionen mit stop() und warning() schreiben