Skip to content

fix(core): add retry with backoff and clear timeout errors#197

Merged
HugoRCD merged 3 commits intomainfrom
fix/adapter-retry-timeout
Mar 15, 2026
Merged

fix(core): add retry with backoff and clear timeout errors#197
HugoRCD merged 3 commits intomainfrom
fix/adapter-retry-timeout

Conversation

@HugoRCD
Copy link
Owner

@HugoRCD HugoRCD commented Mar 15, 2026

This pull request adds robust retry logic with exponential backoff to all HTTP drain adapters in the evlog package, improves timeout error messages, and introduces a configurable retries option for each adapter. The main goal is to make network operations more resilient to transient failures while providing clearer diagnostics.

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.
@HugoRCD HugoRCD self-assigned this Mar 15, 2026
@vercel
Copy link

vercel bot commented Mar 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
evlog-docs Ready Ready Preview, Comment, Open in v0 Mar 15, 2026 7:49pm

@github-actions github-actions bot added the bug Something isn't working label Mar 15, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 15, 2026

Thank you for following the naming conventions! 🙏

@HugoRCD HugoRCD requested a review from Copilot March 15, 2026 19:29
@github-actions
Copy link
Contributor

github-actions bot commented Mar 15, 2026

Benchmark report

Bundle size

Threshold: 5% · 🔴 larger · 🟡 warning · 🟢 smaller · ⚪ unchanged · 🆕 new

Status Entry Base (gzip) Current (gzip) Change Raw delta
🆕 framework/vite 2.38 kB new +7.11 kB
🆕 framework/ai 1.98 kB new +6.43 kB
🆕 client 118 B new +166 B
adapter/better-stack 1.08 kB 1.09 kB +1.5% +48 B
adapter/axiom 1.30 kB 1.32 kB +1.4% +48 B
adapter/posthog 1.48 kB 1.50 kB +1.1% +75 B
adapter/sentry 2.33 kB 2.34 kB +0.6% +48 B
adapter/otlp 2.09 kB 2.10 kB +0.5% +48 B
framework/nitro 6.85 kB 6.85 kB 0.0% 0 B
logger 3.78 kB 3.78 kB 0.0% 0 B
framework/next 3.02 kB 3.02 kB 0.0% 0 B
enrichers 1.92 kB 1.92 kB 0.0% 0 B
framework/sveltekit 1.54 kB 1.54 kB 0.0% 0 B
adapter/fs 1.41 kB 1.41 kB 0.0% 0 B
utils 1.41 kB 1.41 kB 0.0% 0 B
pipeline 1.35 kB 1.35 kB 0.0% 0 B
browser 1.21 kB 1.21 kB 0.0% 0 B
error 1.21 kB 1.21 kB 0.0% 0 B
framework/nestjs 1.21 kB 1.21 kB 0.0% 0 B
framework/elysia 1.07 kB 1.07 kB 0.0% 0 B
framework/fastify 1009 B 1009 B 0.0% 0 B
workers 960 B 960 B 0.0% 0 B
framework/express 701 B 701 B 0.0% 0 B
framework/hono 594 B 594 B 0.0% 0 B
toolkit 242 B 242 B 0.0% 0 B
core (index) 205 B 205 B 0.0% 0 B
types 31 B 31 B 0.0% 0 B
🔴 Total 37.90 kB 42.45 kB +12.0% +13.96 kB

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 15, 2026

npm i https://pkg.pr.new/evlog@197
npm i https://pkg.pr.new/@evlog/nuxthub@197

commit: dc0e3ea

@codspeed-hq
Copy link

codspeed-hq bot commented Mar 15, 2026

Merging this PR will degrade performance by 37.01%

⚡ 4 improved benchmarks
❌ 2 regressed benchmarks
✅ 90 untouched benchmarks

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
consola (withTag.info) 284.2 µs 451.2 µs -37.01%
winston 556.9 µs 771.9 µs -27.86%
pino 443.4 µs 347.4 µs +27.65%
push 1100 events (100 dropped, buffer=1000) 2.1 ms 1.9 ms +11.18%
push 1000 events (no flush) 2.3 ms 1.8 ms +23.23%
with traceparent 340.9 µs 304.7 µs +11.89%

Comparing fix/adapter-retry-timeout (dc0e3ea) with main (abda28c)1

Open in CodSpeed

Footnotes

  1. No successful run was found on main (cd31649) during the generation of this report, so abda28c was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 retries on HTTP drain adapter configs (Axiom, OTLP, Sentry, PostHog, Better Stack) and forwards it into the shared httpPost helper.
  • 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.

@HugoRCD HugoRCD merged commit 3601d30 into main Mar 15, 2026
15 of 16 checks passed
@HugoRCD HugoRCD deleted the fix/adapter-retry-timeout branch March 15, 2026 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants