Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The project enables developers to build reactive decentralized applications with

CI quality checks: [dashboard accessibility](docs/accessibility-automation.md),
[listener Node.js support](listener/docs/node-compatibility.md),
[webhook response classification](listener/docs/webhook-response-classification.md),
[critical event mutation testing](listener/docs/mutation-testing.md), and
[contract build reproducibility](docs/CONTRACT_BUILD_REPRODUCIBILITY.md).

Expand Down
29 changes: 29 additions & 0 deletions listener/docs/webhook-response-classification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Webhook response classification

Webhook delivery outcomes are classified by
`listener/src/services/webhook-retry-helper.ts` so retries use one rule set.
The classification is exercised by
`listener/src/services/webhook-retry-helper.test.ts`.

| Outcome | HTTP response / error | Retried? |
| ------- | --------------------- | -------- |
| Success | Any `2xx` | No |
| Retryable | `408`, `425`, `429`, any `5xx`, request timeout, network error | Yes, bounded |
| Permanent | `400`, `401`, `403`, `404`, `410`, `422`, other `4xx`, `1xx`, `3xx` | No |

## Rules

1. A response with a `2xx` status is a success.
2. `408`, `425`, `429`, and every `5xx` status are retryable.
3. Timeouts and network-level failures are retryable.
4. Explicit permanent client errors (`400`, `401`, `403`, `404`, `410`, `422`)
and any other non-retryable status are permanent.
5. Retries are bounded to the initial attempt plus two retries (`MAX_RETRY_ATTEMPTS`)
with a fixed delay (`RETRY_DELAY_MS`), so a permanent failure cannot loop
indefinitely.
6. A response that is neither successful nor explicitly retryable defaults to
permanent. An unknown classification therefore under-retries rather than
retrying forever.

The delivery path and the retry helper both call `classifyWebhookFailure`, so
changing a status code here changes both consistently.