-
Notifications
You must be signed in to change notification settings - Fork 6
Description
Summary
When using withBetterStack() and <BetterStackWebVitals />, requests to POST /_betterstack/web-vitals are rewritten to the Better Stack ingest URL. If that external request fails (e.g. network timeout, ingest down, or firewall), Next.js surfaces the error to the client as 500 Internal Server Error. This affects development and any environment where the ingest endpoint is slow or unreachable.
Environment
- Package:
@logtail/nextv0.3.1 - Next.js: 16.x (Turbopack) With proxy.ts
- Node: 22+
Steps to reproduce
- Configure Better Stack with valid
NEXT_PUBLIC_BETTER_STACK_SOURCE_TOKENandNEXT_PUBLIC_BETTER_STACK_INGESTING_URL(e.g.https://sXXXX.eu-nbg-2.betterstackdata.com). - Use
withBetterStack(nextConfig)innext.config.tsand render<BetterStackWebVitals />in the root layout. - Simulate an unreachable ingest (e.g. block the domain, use an invalid URL, or rely on a slow/unstable network).
- Load the app and let the client send web vitals to
/_betterstack/web-vitals.
Expected behavior
- The client receives a 2xx response (e.g. 204 No Content) when the ingest is unreachable, so that:
- The app does not show failed network requests or 500s in the console.
- Telemetry failure does not impact user-facing behavior.
- Optionally: the proxy could use a timeout (e.g. 5s) and return 204 on timeout/error instead of propagating the failure.
Actual behavior
- The proxy request to the ingest URL fails (e.g.
ETIMEDOUT). - Next.js returns 500 Internal Server Error to the client for
POST /_betterstack/web-vitals. - Browser console shows:
POST http://localhost:3000/_betterstack/web-vitals 500 (Internal Server Error). - Server logs show:
Failed to proxy https://sXXXX.eu-nbg-2.betterstackdata.com/ AggregateError: { code: 'ETIMEDOUT' }.
Possible fix
In the rewrite/proxy layer that handles /_betterstack/web-vitals (and optionally /_betterstack/logs):
- Forward the request to the ingest URL with a timeout (e.g. 5s).
- On timeout or network error, return 204 No Content (or another 2xx) instead of 500, so the client does not see a failure.
- Optionally log the error server-side for debugging.
Workaround
We added a custom Route Handler at app/_betterstack/web-vitals/route.ts that runs before the config rewrite. It forwards the POST to the ingest URL with an AbortController timeout (5s) and returns 204 on any error. That way the client never receives 500 when the ingest is unreachable.