Skip to content

[T-17107] Return 204 from telemetry proxy when the ingest endpoint is unreachable#36

Open
Naerriel wants to merge 2 commits into
logtail:mainfrom
Naerriel:karol/t-17107-web-vitals-proxy-returns-500-when-ingest-endpoint-is
Open

[T-17107] Return 204 from telemetry proxy when the ingest endpoint is unreachable#36
Naerriel wants to merge 2 commits into
logtail:mainfrom
Naerriel:karol/t-17107-web-vitals-proxy-returns-500-when-ingest-endpoint-is

Conversation

@Naerriel

@Naerriel Naerriel commented Jul 6, 2026

Copy link
Copy Markdown

Fixes #35 (Linear T-17107).

The web vitals and logs proxy is a plain Next.js rewrite, and Next.js turns any upstream failure (e.g. ETIMEDOUT when the ingest endpoint is unreachable) into a 500 served from the app own domain - there is no way to intercept that from next.config. This adds an opt-in route handler that serves the proxy path instead of the rewrite: it forwards the payload with a 5s timeout and always responds 204, logging delivery failures server-side only. Users mount it with a one-liner: export { POST } from '@logtail/next/proxy'.

Because underscore-prefixed app router folders are private and excluded from routing (and the %5F escape does not work with Turbopack), the handler cannot be mounted on the default /_betterstack path. The proxy path is therefore overridable via NEXT_PUBLIC_BETTER_STACK_PROXY_PATH, which keeps the client-side sender and the rewrites in sync automatically. The route files must be static (app/betterstack/web-vitals/route.ts and app/betterstack/logs/route.ts), not a [...path] catch-all - Next.js checks afterFiles rewrites before dynamic routes, so a catch-all is shadowed by the rewrite. Verified end-to-end on Next 16.2.10 with Turbopack: with the ingest endpoint down the client now gets 204 instead of 500, and with it up the payload and Authorization header pass through intact.

Naerriel and others added 2 commits July 6, 2026 10:54
… unreachable

The /_betterstack rewrites let Next.js proxy browser telemetry, but Next.js
turns any upstream failure (e.g. ETIMEDOUT) into a 500 on the app own domain.
The new opt-in route handler serves the proxy path instead: it forwards with
a timeout and always responds 204, logging delivery failures server-side.
The proxy path is now overridable via NEXT_PUBLIC_BETTER_STACK_PROXY_PATH
because underscore-prefixed app router folders are private and cannot host
route handlers.

Fixes logtail#35

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Naerriel

Naerriel commented Jul 6, 2026

Copy link
Copy Markdown
Author

@PetrHeinz Can I have a review, please? 🙏

@PetrHeinz PetrHeinz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @Naerriel! 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Web Vitals proxy returns 500 when ingest endpoint is unreachable (e.g. ETIMEDOUT)

2 participants