fix(core): add retry with backoff and clear timeout errors#197
Conversation
Transient failures (timeouts, network errors, 5xx) are now retried up to 2 times with exponential backoff. AbortError is caught and rethrown with a human-readable message indicating the timeout duration.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Thank you for following the naming conventions! 🙏 |
Benchmark reportBundle size
|
commit: |
Merging this PR will degrade performance by 37.01%
Performance Changes
Comparing Footnotes |
There was a problem hiding this comment.
Pull request overview
Adds configurable retries with exponential backoff to the shared HTTP posting helper used by the evlog HTTP drain adapters, and updates adapter configs/tests accordingly.
Changes:
- Introduces
retrieson HTTP drain adapter configs (Axiom, OTLP, Sentry, PostHog, Better Stack) and forwards it into the sharedhttpPosthelper. - Implements retry + exponential backoff and improves timeout error messages in
httpPost. - Updates adapter tests to accommodate multiple fetch attempts, and adds a changeset entry.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/evlog/src/adapters/_http.ts | Adds retry/backoff logic and improved timeout error message in the shared HTTP helper. |
| packages/evlog/src/adapters/axiom.ts | Adds retries config and passes it through to httpPost. |
| packages/evlog/src/adapters/otlp.ts | Adds retries config and passes it through to httpPost. |
| packages/evlog/src/adapters/posthog.ts | Adds retries config and passes it through to httpPost (and OTLP config mapping). |
| packages/evlog/src/adapters/sentry.ts | Adds retries config and passes it through to httpPost. |
| packages/evlog/src/adapters/better-stack.ts | Adds retries config and passes it through to httpPost. |
| packages/evlog/test/adapters/otlp.test.ts | Adjusts fetch mocking for retry behavior in a 5xx test. |
| packages/evlog/test/adapters/posthog.test.ts | Adjusts fetch mocking for retry behavior in a 5xx drain test. |
| .changeset/adapter-retry-timeout.md | Documents the retry/backoff + timeout message changes for release notes. |
Comments suppressed due to low confidence (2)
packages/evlog/test/adapters/otlp.test.ts:311
- With retries/backoff enabled, this test now waits ~600ms in real time (200ms + 400ms) before rejecting, which can slow down the suite and become flaky. Consider switching to fake timers here and asserting the expected retry behavior (e.g. number of fetch attempts) while advancing timers deterministically.
it('throws error on non-OK response', async () => {
fetchSpy.mockResolvedValue(
new Response('Internal Server Error', { status: 500, statusText: 'Internal Server Error' }),
)
const event = createTestEvent()
await expect(sendToOTLP(event, {
endpoint: 'http://localhost:4318',
})).rejects.toThrow('OTLP API error: 500 Internal Server Error')
})
packages/evlog/test/adapters/posthog.test.ts:351
- This test will now incur the real retry backoff delays (~600ms total) before reaching the catch/log path. To keep the adapter test suite fast and deterministic, consider using fake timers and (optionally) asserting the expected number of retry attempts.
it('catches and logs errors from sendBatchToOTLP', async () => {
fetchSpy.mockResolvedValue(
new Response('Internal Server Error', { status: 500, statusText: 'Internal Server Error' }),
)
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
const drain = createPostHogDrain({ apiKey: 'phc_test' })
await drain(createDrainContext())
expect(consoleSpy).toHaveBeenCalledWith(
'[evlog/posthog] Failed to send events:',
expect.any(Error),
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
This pull request adds robust retry logic with exponential backoff to all HTTP drain adapters in the
evlogpackage, improves timeout error messages, and introduces a configurableretriesoption for each adapter. The main goal is to make network operations more resilient to transient failures while providing clearer diagnostics.