Skip to content

Error Classification

Sparrow classifies every delivery error into one of 9 categories. The classification determines whether the delivery is retried or permanently failed.

CategoryRetryableDescription
successn/aDelivery succeeded
client_errorNoHTTP 4xx response (bad request, unauthorized, not found, etc.)
server_errorYesHTTP 5xx response (internal server error, bad gateway, etc.)
timeoutYesRequest timed out before receiving a response
connection_refusedYesTarget endpoint refused the TCP connection
network_errorYesOther network errors (ECONNRESET, EPIPE, EHOSTUNREACH)
dns_errorNoDNS resolution failed (no such host)
tls_errorNoTLS/SSL handshake failure (certificate errors)
unknownNoUnclassified error

When a delivery attempt fails with a retryable error category, Sparrow re-enqueues the delivery with exponential backoff:

backoff = retry_backoff_seconds * 2^(attempt - 1) + random_jitter

Retries continue until:

  • The delivery succeeds
  • max_retries attempts are exhausted (terminal FAILED status)
  • The event’s ttl_seconds expires (terminal EXPIRED status)

Non-retryable errors immediately mark the delivery as FAILED regardless of remaining retry budget.

The error classifier inspects the Go error chain to determine the category:

  1. HTTP response code — If a response was received:

    • 2xx matching expected_status_codes -> success
    • 4xx -> client_error
    • 5xx -> server_error
  2. Error type inspection — If no response:

    • *net.DNSError -> dns_error
    • TLS-related errors -> tls_error
    • net.Error with Timeout() -> timeout
    • syscall.ECONNREFUSED -> connection_refused
    • syscall.ECONNRESET, EPIPE, EHOSTUNREACH -> network_error
    • String pattern fallback for edge cases

Use the HealthService to monitor error patterns:

  • GetWebhookHealth returns error category breakdown (client_errors, server_errors, timeout_errors, network_errors) for the last 24 hours
  • ListWebhooksByHealth finds all webhooks with UNHEALTHY or DEGRADED status
  • GetDeliveryAttempts shows per-attempt error details for debugging