Files
projektuebersicht/node_modules/undici/docs/docs/api/RetryHandler.md
T
erikandClaude Sonnet 5 6ba93b2a92 Plan Checker, Wochenbericht-Fokus-Modus und Wandtafel-Dashboard-Feinschliff
Plan Checker (neues Studenten-Werkzeug, Seitenleiste + Admin → Plan-Checker-
Merkmale): lädt einen Bauplan als PDF hoch und lässt ChatGPT oder Claude ihn
gegen eine gepflegte Merkmalsliste prüfen. PDF-Rendering (pdf.js +
@napi-rs/canvas) berücksichtigt jetzt Ebenen (Optional Content Groups) und
WASM-Decoder korrekt, sendet eine Übersicht plus mehrere hochaufgelöste
Kachel-Ausschnitte statt eines einzelnen, zu groben Bilds, und beide Anbieter
bekommen dasselbe Bildmaterial. Jedes Prüfergebnis kann auf eines der
gesendeten Bilder als Beleg verweisen (bildIndex) — als Screenshot im
Ergebnis anklickbar, öffnet vergrößert in einem Modal statt eines von Chrome
blockierten target=_blank-Links auf eine data:-URL. KI-Modellname ist jetzt
pro Konto überschreibbar (Einstellungen → Mein Konto) für Drittanbieter mit
abweichendem Modell-Katalog.

Wochenbericht: dichte Kartenansicht bekommt einen Fokus-Modus — nur der
Kommentar liegt offen, Leistungsphasen und Beteiligte stecken in
aufklappbaren Abschnitten statt dauerhaft nebeneinander zu stehen.

Projektbereich: Terminplan-Auslastung rechnet jetzt exakt wie der
Auslastungs-Tab/die Wandtafel (statt einer unabhängigen, tageweisen
Schätzung); die LPH-Fortschrittsliste im Dashboard zeigt nur noch die
beauftragten Leistungsphasen.

Wandtafel: Dashboard-Kopf mit Kennzahlen-Reihe und Panel-Reihe neu
strukturiert, in den Blautönen des Firmenlogos; dieselbe Palette wurde
anschließend auf den gesamten App-weiten Dark Mode übernommen.

Dateibereinigung: nicht mehr benötigte Test-Uploads/Backups entfernt.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-05 14:01:41 +02:00

7.2 KiB

RetryHandler

Stability: 2 - Stable

A Dispatcher handler that automatically retries a request when it fails with a recoverable network error or an eligible HTTP status code. It wraps an inner handler and re-dispatches the request, applying an exponential backoff and honouring the Retry-After response header. When a response is partially consumed before the failure, the handler resumes the download with a Range request guarded by the original ETag.

The handler is most often used indirectly through RetryAgent, but it can also be supplied directly to dispatcher.dispatch() for fine-grained control over the retry behaviour.

import { RetryHandler } from 'undici'

Class: RetryHandler

  • Extends: {DispatchHandler}

Implements the DispatchHandler interface. An instance is consumed by a single dispatch call and forwards the dispatch lifecycle to the inner handler, re-issuing the request through the supplied dispatch function whenever a retry is warranted.

Note: The RetryHandler does not retry over stateful bodies (for example streams or AsyncIterable), because once consumed they cannot be replayed. In these situations the body is identified as stateful and the request is rejected with the UND_ERR_REQ_RETRY error instead of being retried.

new RetryHandler(options, retryHandlers)

  • options {DispatchOptions} The dispatch options for the request, extended with an optional retryOptions field. Type is DispatchOptions & { retryOptions?: RetryOptions }.
    • retryOptions {RetryOptions} (optional) Configuration controlling when and how the request is retried. See RetryOptions.
  • retryHandlers {RetryHandlers} The handlers used to drive the retry loop. See RetryHandlers.
  • Returns: {RetryHandler}

RetryOptions

  • throwOnError {boolean} When true, an error is thrown on the last retry attempt and propagated to the inner handler; when false, the failing response is passed through instead, which is useful when the error body is needed or a custom error handler is in place. Default: true.
  • retry {Function} Callback invoked on every retry iteration to decide whether another attempt should be made. It receives the error, the retry context, and a callback. Call the callback with an Error to stop retrying, or with null to schedule another attempt. Default: the built-in retry strategy described below.
    • err {Error} The error that triggered the retry.
    • context {RetryContext} The current retry context. See RetryContext.
    • callback {Function} Signals the outcome of this iteration.
      • result {Error|null} (optional) An Error to abort retrying, or null to retry.
  • maxRetries {number} Maximum number of retries allowed. Default: 5.
  • maxTimeout {number} Maximum number of milliseconds to wait between retries. Default: 30000 (30 seconds).
  • minTimeout {number} Initial number of milliseconds to wait before the first retry. Default: 500 (half a second).
  • timeoutFactor {number} Multiplier applied to the timeout between successive retries to produce an exponential backoff. Default: 2.
  • retryAfter {boolean} When true, the delay before the next retry is inferred from the Retry-After response header when present. Default: true.
  • methods {string[]} HTTP methods that are eligible for retrying. Default: ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE'].
  • statusCodes {number[]} HTTP status codes that trigger a retry. Default: [500, 502, 503, 504, 429].
  • errorCodes {string[]} Network error codes that trigger a retry. Default: ['ECONNRESET', 'ECONNREFUSED', 'ENOTFOUND', 'ENETDOWN', 'ENETUNREACH', 'EHOSTDOWN', 'EHOSTUNREACH', 'EPIPE', 'UND_ERR_SOCKET'].

The default retry strategy computes the delay before the next attempt as minTimeout * timeoutFactor ** (counter - 1), capped at maxTimeout. When a Retry-After header is present it takes precedence (interpreted as seconds, or as an HTTP date), still capped at maxTimeout. The default strategy stops retrying once counter exceeds maxRetries, when the error code is not in errorCodes, when the method is not in methods, or when the response status code is not in statusCodes.

RetryContext

  • state {RetryState} The current retry state. See RetryState.
  • opts {DispatchOptions} The dispatch options passed to the handler, including the resolved retryOptions. Type is DispatchOptions & { retryOptions?: RetryOptions }.

The context object passed as the second argument to the retry callback.

RetryState

  • counter {number} The current retry attempt, starting at 1 for the first retry.

Represents the retry state for a given request.

Parameter: RetryHandlers

  • dispatch {Function} The dispatch function called to (re-)issue the request on every attempt. Type is (options, handler) => boolean.
  • handler {DispatchHandler} The inner handler invoked once the request succeeds or the retries are exhausted.

Examples

import { Client, RetryHandler } from 'undici'

const client = new Client(`http://localhost:${server.address().port}`)
const chunks = []

const handler = new RetryHandler(
  {
    ...dispatchOptions,
    retryOptions: {
      // Custom retry decision function.
      retry (err, { state, opts }, callback) {
        if (err.code === 'UND_ERR_DESTROYED') {
          callback(err)
          return
        }

        if (err.statusCode === 206) {
          callback(err)
          return
        }

        setTimeout(() => callback(null), 1000)
      }
    }
  },
  {
    dispatch (...args) {
      return client.dispatch(...args)
    },
    handler: {
      onRequestStart () {},
      onResponseStart (controller, status, headers) {
        // Do something with the response headers.
      },
      onResponseData (controller, chunk) {
        chunks.push(chunk)
      },
      onResponseEnd () {},
      onResponseError (controller, err) {
        // Handle the error.
      }
    }
  }
)

client.dispatch(dispatchOptions, handler)

A minimal handler that relies entirely on the default retry options:

import { Client, RetryHandler } from 'undici'

const client = new Client(`http://localhost:${server.address().port}`)

const handler = new RetryHandler(dispatchOptions, {
  dispatch: client.dispatch.bind(client),
  handler: {
    onRequestStart () {},
    onResponseStart (controller, status, headers) {},
    onResponseData (controller, chunk) {},
    onResponseEnd () {},
    onResponseError (controller, err) {}
  }
})

client.dispatch(dispatchOptions, handler)