Repository navigation
Conversation
ec2da8d to
2933944
Compare
applyManagedTunnel to point the tunnel at the DSN-derived pathtunnel: true in init to enable the managed tunnel
size-limit report 📦Compared: 3a5171f (PR test merge using develop at 8c4491d) Against: ca4fc32 (develop) · base run #62950
|
2933944 to
4837dc0
Compare
d5c110f to
4ab6297
Compare
4ab6297 to
bf1d62c
Compare
75a299e to
b1553a8
Compare
b1553a8 to
0e573ca
Compare
tunnel: true in init to enable the managed tunneltunnel: true in the SDKs that serve the managed tunnel
1d77f74 to
80f1700
Compare
tunnel: true in the SDKs that serve the managed tunneltunnel: true in init to enable the managed tunnel
a769b10 to
d79df66
Compare
|
bugbot run |
d79df66 to
8717465
Compare
|
bugbot run |
1 similar comment
|
bugbot run |
Optional E2E testsSome optional checks were not successful. They do not block the merge. 1 not successful, 64 successful. See the run.
Successful checks
|
aeb40b0 to
aee0a31
Compare
aee0a31 to
3d0e344
Compare
Lms24
left a comment
There was a problem hiding this comment.
Had some questions mostly. I don't love the 0.5KB bundle size hit on the browser but I guess there's not much we can do here. Not sure if you tried it but would moving the managedTunnelTransport logic into the fetchTransport help reducing a bit of size footprint?
| * | ||
| * @default undefined | ||
| */ | ||
| tunnel?: TunnelInit; |
There was a problem hiding this comment.
A relative path, e.g.
/monitor, enables the managed tunnel at that fixed path. The browser sends envelopes to it and the server SDK serves it, so set the same path in bothinits.
dumb q and I probably missed something in the first PR: What happens if a user sets tunnel: '/my-endpoint' and expects to fully manage the tunnel endpoint themselves? Just wondering since the JSDoc says it enables the managed tunnel if this is still possible
There was a problem hiding this comment.
could it be that this doc is outdated? Given we don't set _managedTunnel when users pass a string…
There was a problem hiding this comment.
That's a good point, there is a bit of a fork here, if the user does:
tunnel: true // new behavior
tunnel: { path } // new behavior
tunnel: `/watever` // old behavior
Which I don't like 🤔 since you brought it up its better to resolve it here.
Ideally I want all to behave the same, and from a browser standpoint, that only matters in the resend fallback. The fallback doesn't kick in for non managed cases right now, but what i am saying is the browser shouldn't care about the tunnel being managed or not.
So my current idea is:
- 200s are fine, no fallback what so ever there, i verified most static page providers, they never respond with a 200 for a post request for a page that doesn't exist, always 404 or 405. so that concern was invalid.
- 4xx
- if Sentry tunnel header tag present, no fallback, it came from Sentry.
- If header not present, it came from the app, fallback activates.
So the breaking change case is the last one, I'm thinking we only add the fallback for 404/405 and keep everything else fallback-less. That makes it less aggressive and won't trigger for that use case as much.
| * Falls back to sending directly when nothing on this origin serves the managed tunnel. An envelope is resent only | ||
| * when the response proves it never reached Sentry. | ||
| */ | ||
| export function makeManagedTunnelTransport( |
There was a problem hiding this comment.
I was a bit hesitant first if sending directly to Sentry is a good fallback decision. But then again, this would only apply for a managed tunnel, which is new behaviour users have to opt into. That's fine I think. My concern was primarily about users explicitly not wanting to send directly, but every use case I could come up with (custom Relay, scrubbing, cleaning headers, etc) would require a custom tunnel implementation anyway. So I think this is fine. Wanted to leave here as food for thought if you agree with this or if you could see other cases where the fallback behaviour might not be ideal.
There was a problem hiding this comment.
See my comment up there. I will make changes here.
| // Not the tunnel: a 4xx never reached Sentry so it's resent, a 2xx may have, so only later envelopes go direct. | ||
| const rejected = statusCode >= 400 && statusCode < 500; | ||
| const { dsn, sdk } = envelope[0]; | ||
| const components = (rejected || (statusCode >= 200 && statusCode < 300)) && dsn && makeDsn(dsn); | ||
| if (!components) { | ||
| return response; | ||
| } |
There was a problem hiding this comment.
related to my comment above: What's the real world use case how this can happen? I assume it would be someone manually not configuring the server managed tunnel, correct? Also, can we be sure that 4xx responses never come from Sentry? I primarily want to make sure we don't resend when we already got rate limited.
There was a problem hiding this comment.
Also, can we be sure that 4xx responses never come from Sentry
It depends, if they use a server SDK or our utils to handle the tunnel request then we will know because our utils tag the response with a header. if the header is present then we know it is from sentry and no fallback is triggered.
I'm making a couple of changes here:
- Fallback will be limited to 404/405 responses because those would be misconfigured tunnels, unless it was from Sentry.
- Everything else works the same without fallback.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 2d2f6a9. Configure here.
Setting `tunnel: true` (or `{ allowedDsns, basePath, trailingSlash }`) in both
the browser and the server `init` enables the managed tunnel. The browser
resolves it to the DSN-derived same-origin path and sends envelopes as
`application/x-sentry-envelope`, because SvelteKit and Astro CSRF checks reject
a same-origin `text/plain` POST. Server SDKs keep their own envelopes going
directly to Sentry and set `_managedTunnel` for their request handlers.
With `debug: true`, the client warns once when a managed tunnel request gets a 403, 404 or 405, pointing at the server side: a meta-framework SDK, an endpoint calling `handleTunnelRequest`, or `allowedDsns`.
…naged tunnel request with a 4xx
…port, and import server helpers from core/server Only the browser sends to a managed tunnel, so the warning moves from the shared Client into the browser's tunnel transport. Server SDKs import resolveServerTunnelOption from @sentry/core/server.
The reason strings were built in production bundles too, while only the debug warning that printed them was stripped.
…nel tests `isTunnelRequest` only reads the active server client now, and the paths are already checked against `getTunnelPath`.
…path, which is the managed tunnel to serve
… fall back on 404 or 405

Previously the client side only accepted a
stringtunnel option so it sent the requests to that fixed endpoint, this PR effectively adds "managed" tunnel support that is generated automatically from the provided DSN.This PR adds the tunnel options to the SDKs's
initoptions and implements the client transport if the tunnel is provided.On the server side the runtime SDKs only translate
tunnel: trueinto the internal_managedTunneloption, answering the requests is left to the meta-frameworks in the rest of the stack.For reviewers: if you need an overview of what this is, refer to #25199.
closes #25460