feat(core, node): portable Connect integration#20882
Conversation
Platform-portable Connect tracing integration in `@sentry/core` (`patchConnectModule`, `setupConnectErrorHandler`), similar to portable Express integration, and rewire the Node SDK's Connect integration to call into it through the otel InstrumentationBase class. Remove OTel-specific span attribute fix-up. Spans created with correct origin (`auto.http.connect`) and op directly in the middleware.
051bd5b to
93b0b34
Compare
Platform-portable Connect tracing integration in `@sentry/core` (`patchConnectModule`, `setupConnectErrorHandler`), similar to portable Express integration, and rewire the Node SDK's Connect integration to call into it through the otel InstrumentationBase class. Remove OTel-specific span attribute fix-up. Spans created with correct origin (`auto.http.connect`) and op directly in the middleware.
93b0b34 to
eebfaa1
Compare
size-limit report 📦
|
Platform-portable Connect tracing integration in `@sentry/core` (`patchConnectModule`, `setupConnectErrorHandler`), similar to portable Express integration, and rewire the Node SDK's Connect integration to call into it through the otel InstrumentationBase class. Remove OTel-specific span attribute fix-up. Spans created with correct origin (`auto.http.connect`) and op directly in the middleware.
eebfaa1 to
52c43e5
Compare
Platform-portable Connect tracing integration in `@sentry/core` (`patchConnectModule`, `setupConnectErrorHandler`), similar to portable Express integration, and rewire the Node SDK's Connect integration to call into it through the otel InstrumentationBase class. Remove OTel-specific span attribute fix-up. Spans created with correct origin (`auto.http.connect`) and op directly in the middleware.
52c43e5 to
32896c0
Compare
| return originalHandle.apply(this, args); | ||
| }); | ||
| } catch (e) { | ||
| DEBUG_BUILD && debug.error('Failed to patch connect handle method:', e); |
There was a problem hiding this comment.
Bug: When the handle method is called without an out callback, the stack layer added by addNewStackLayer is never removed, causing route stack corruption on subsequent calls.
Severity: HIGH
Suggested Fix
The completeStack() function should be called to clean up the stack layer after originalHandle completes, regardless of whether an out callback was provided. This can be achieved by calling it after the originalHandle.apply call, ensuring the layer is always popped.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: packages/core/src/integrations/connect/index.ts#L254
Potential issue: The patched `handle` method calls `addNewStackLayer(req)` to push a new
layer onto the route stack. However, the corresponding cleanup function,
`completeStack()`, is only scheduled to be called within a patched `out` callback.
According to Connect.js documentation, the `out` callback is optional and often omitted
in nested application scenarios. When `handle` is invoked without `out`, a layer is
pushed but never popped. If the same request object is reused across multiple `handle`
calls, this leads to an accumulation of stale layers, corrupting the route stack and
causing `generateRoute(req)` to report incorrect route names.
Did we get this right? 👍 / 👎 to inform future reviews.
|
This actually needs to be somewhat re-factored to work off the now-vendored Connect integration. And, tbh, it might make more sense to go with orchestrion, and make it a v11 integration anyway. This was always a somewhat experimental low-stakes/low-value patch, so it's no great loss. Not a ton of people using Connect anyway, compared with Express and other node frameworks. Closing this for now. |
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 32896c0. Configure here.
| const app = connect.apply(this, args) as ConnectApp; | ||
| patchConnectApp(app, options); | ||
| return app; | ||
| } as ConnectModule; |
There was a problem hiding this comment.
Connect export loses static props
Medium Severity
patchConnectModule returns a new factory function and the Node instrumentation hook uses that as the patched connect export. Unlike the in-place Express patch, nothing copies static members from the original export (for example connect.mime), so code that reads them after Sentry.init() breaks.
Reviewed by Cursor Bugbot for commit 32896c0. Configure here.


Platform-portable Connect tracing integration in
@sentry/core(patchConnectModule,setupConnectErrorHandler), similar to portable Express integration, and rewire the Node SDK's Connect integration to call into it through the otel InstrumentationBase class.Remove OTel-specific span attribute fix-up. Spans created with correct origin (
auto.http.connect) and op directly in the middleware.