R Academy · Les

withCallingHandlers() en restarts

Gebruik withCallingHandlers() voor niet-lokale afhandeling van condities.

Les 3 van 413 stappen

withCallingHandlers() en restarts is een gratis R Academy-les op CoddyKit. Dit is les 3 van 4. Je kunt 3 lessen uit dit leerpad gratis volledig lezen — daarna ontgrendelt CoddyKit PRO alle lessen, plus praktische oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. Deze les maakt deel uit van het leertraject R Academy. Je voortgang wordt gesynchroniseerd op het web en in de CoddyKit-app. De cursus R Academy bevat in totaal 4 lessen.

tryCatch versus withCallingHandlers

Het belangrijkste verschil: tryCatch() brengt een niet-lokale exit tot stand — zodra een voorwaarde is opgevangen, wordt de besturing buiten de expressie overgedragen en keert de uitvoering niet terug. withCallingHandlers() houdt de aanroepstack intact en kan de uitvoering na de afhandeling hervatten.

# 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 houdt de uitvoering gaande

Met withCallingHandlers() wordt de verwerker uitgevoerd, maar gaat de uitvoering verder nadat de voorwaarde is gesignaleerd (tenzij de verwerker zelf een fout veroorzaakt of een herstart aanroept). De aanroepstack wordt niet afgewikkeld.

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')
})

De herstart muffleWarning

Als je binnen een waarschuwingverwerker invokeRestart('muffleWarning') aanroept, onderdruk je dat de waarschuwing door de standaardverwerker van R wordt afgedrukt. Zonder deze aanroep zou R de waarschuwing na uitvoering van jouw verwerker nog steeds via de standaardafhandeling afdrukken.

# Without muffleWarning: warning still shows after handler
withCallingHandlers({
  warning('test')
}, warning = function(w) {
  cat('Handler ran\n')
  # no muffleWarning: default handler still fires
})

De herstart muffleMessage

Op dezelfde manier maakt invokeRestart('muffleMessage') binnen een berichtverwerker het bericht stil nadat jouw aangepaste verwerker het heeft verwerkt. Dit is het mechanisme achter suppressMessages().

withCallingHandlers({
  message('Progress: 50%')
  message('Progress: 100%')
}, message = function(m) {
  cat('[LOG]', trimws(m$message), '\n')
  invokeRestart('muffleMessage')
})

Waarschuwingen loggen zonder te stoppen

Een praktisch gebruik van withCallingHandlers(): verzamel waarschuwingen in een logvector terwijl de code kan worden voltooid. tryCatch() zou bij de eerste waarschuwing stoppen; withCallingHandlers() verzamelt ze allemaal.

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')

Het concept invokeRestart()

Herstarts zijn vooraf gedefinieerde herstelstrategieën die de code die de voorwaarde signaleert kan aanbieden. Met invokeRestart(name) selecteer je een van deze strategieën. Ingebouwde herstarts zijn onder andere 'muffleWarning' en 'muffleMessage'; je kunt aangepaste herstarts definiëren met 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 en tryCatch combineren

Je kunt de twee nesten: gebruik aan de buitenkant withCallingHandlers() om voorwaarden te loggen of te tellen, en aan de binnenkant tryCatch() om een terugvalwaarde te leveren. De buitenste verwerker ziet de voorwaarde als eerste.

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')

Aangepaste voorwaardeklassen

Je kunt aangepaste voorwaardeklassen maken door structure() aan te roepen op een lijst met klasse c('myError', 'error', 'condition'). Verwerkers zoeken op klasse, dus met aangepaste klassen kun je specifieke fouttypen opvangen zonder alle fouten op te vangen.

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')
)

Wanneer gebruik je withCallingHandlers

Gebruik withCallingHandlers() wanneer je voorwaarden wilt observeren of loggen zonder de uitvoering te stoppen. Gebruik tryCatch() wanneer je van een voorwaarde wilt herstellen en een alternatieve waarde wilt retourneren. Ze lossen verschillende problemen op.

# withCallingHandlers: observe all, continue
withCallingHandlers(
  for (x in c(4, -1, 9, -4)) cat(suppressWarnings(sqrt(x)), ''),
  warning = function(w) cat('[warn]', '')
)
cat('\n')

De keten voor het signaleren van voorwaarden

Wanneer een voorwaarde wordt gesignaleerd, loopt R de aanroepstack omhoog op zoek naar verwerkers. Verwerkers van withCallingHandlers() worden uitgevoerd in de dynamische context (met intacte aanroepstack). Verwerkers van tryCatch() worden uitgevoerd nadat de stack is afgewikkeld — de oorspronkelijke context is verdwenen.

# 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()

Implementatie van suppressWarnings()

suppressWarnings(expr) is in wezen withCallingHandlers(expr, warning = function(w) invokeRestart('muffleWarning')). Als je dit begrijpt, kun je eigen varianten bouwen die alleen bepaalde waarschuwingtypen onderdrukken.

# 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')
)

Snelle controle

Wat is het belangrijkste verschil tussen withCallingHandlers() en tryCatch()?

Herstarts: belangrijkste punten

Belangrijkste punten voor withCallingHandlers en herstarts:

  • withCallingHandlers() = lokale verwerker, aanroepstack intact, uitvoering kan doorgaan
  • tryCatch() = niet-lokale exit, stack afgewikkeld, kan een alternatieve waarde retourneren
  • invokeRestart('muffleWarning') onderdrukt het standaard afdrukken van de waarschuwing
  • invokeRestart('muffleMessage') onderdrukt het standaard afdrukken van het bericht
  • Gebruik withCallingHandlers() om alle voorwaarden te verzamelen of te loggen zonder te stoppen
  • Met aangepaste voorwaardeklassen kun je specifieke fouttypen selectief opvangen
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')
Gratis beginnen

Leer R met een AI-tutor — gratis

Schrijf echte code en voer die uit in je browser, krijg direct hulp van een AI-tutor die 24/7 beschikbaar is en ga verder waar je gebleven bent op het web of in de app.

Cursussen
43
Lessen
159

Veelgestelde vragen

Is de les “withCallingHandlers() en restarts” gratis?

Ja — je kunt hier op het web alle 3 lessen van het leerpad R Academy, waaronder “withCallingHandlers() en restarts”, gratis volledig lezen. Daarna ontgrendelt CoddyKit PRO alle lessen, plus interactieve oefeningen met een ingebouwde code-editor en een AI-tutor die 24/7 beschikbaar is. De cursus R Academy bevat in totaal 4 lessen.

Wat leer ik in “withCallingHandlers() en restarts”?

Gebruik withCallingHandlers() voor niet-lokale afhandeling van condities. Je oefent met R Academy door code rechtstreeks in de browser uit te voeren. Een AI-begeleider die 24/7 beschikbaar is beantwoordt je vragen terwijl je de les doorwerkt.

Heb ik ervaring nodig om met R Academy te beginnen?

Ervaring vooraf is niet nodig. R Academy op CoddyKit is opgebouwd voor beginners tot gevorderden, zodat je hier of bij het begin kunt starten en in je eigen tempo kunt leren. Dit is les 3 van 4.

Hoe lang duurt de les “withCallingHandlers() en restarts”?

De meeste lessen van CoddyKit duren ongeveer 5–10 minuten. Elke les is kort en interactief, zodat je gestaag vooruitgaat en op het web en in de app precies verdergaat waar je was gebleven.

Kan ik code schrijven en uitvoeren in deze les over R Academy?

Ja. Elke les over R Academy bevat een ingebouwde code-editor, zodat je rechtstreeks in je browser echte code kunt schrijven en uitvoeren en direct feedback van AI krijgt — lokale installatie is niet nodig.

Alle lessen in deze cursus

  1. Fouten, waarschuwingen en berichten in R
  2. tryCatch() voor foutafhandeling
  3. withCallingHandlers() en restarts
  4. Robuuste functies schrijven met stop() en warning()
← Terug naar R Academy