Conversation
One package, both halves: the browser SDK for the client and the Node SDK for the server, resolved by export condition. `init()` on each side adds Solid 2's error hook to the platform defaults — every failure a boundary renders a fallback for (client), and every failure the server runtime handles or fails on (server), reported once with where it was thrown and where it was met. Tracing is opt-in and reads Solid's observe tier: one root span per user interaction with its navigations, holds and server-function calls as children (calls joined by the engine's own interaction frame, not by time); a trace provider on `OBSERVE.server.trace` so the runtime carries Sentry's trace to the browser on its own carriers; spans for server-function executions, waiting `<Loading>` boundaries and frame streams; the runtime's diagnostics as issues fingerprinted by code and component path. Element text on interaction targets is user data and left out unless `targetText: true`; a finding's `data.error` is not forwarded as an issue extra. Sibling package to `@sentry/solid` (1.x) for the transition; peer `solid-js`/`@solidjs/web` ^2.0.0-rc.8. Local dev dependencies are `link:` to a local Solid checkout until an rc carrying the record shapes and error hooks this builds on is published. Co-Authored-By: Claude via Cursor <cursoragent@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Swap the local `link:` development dependencies for the published rc.9 — the first release carrying the record shapes, the error hooks and the observe server build the package relies on — and rebuild the lockfile. The tests' Solid inlining moved from Vite's `server.deps` to Vitest's `test.server.deps`, where it belongs: the linked checkout had masked the mistake (paths outside node_modules inline by default), and against the installed packages Node loaded `@solidjs/signals` natively beside the copy Vite inlined — two `OBSERVE`s, and a server half that looked like the wrong tier. The package roots are now resolved from this package rather than assumed hoisted. Co-Authored-By: Claude via Cursor <cursoragent@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Co-Authored-By: Claude via Cursor <cursoragent@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
…ion settled is still its child
Two things the e2e app surfaced against the published rc.9. The record
spans captured the errors they carried (`live.error`), which duplicated the
error hooks: the same error object reaches both, and whichever runs first
wins Sentry's once-per-object guard — the invocation record beat the server
hook and reported a handled boundary catch as an unhandled server-function
crash with the wrong mechanism. The hooks are the one error path; records
set the span's status.
`onClick={async () => set(await call())}` makes no synchronous write, so the
interaction settles as `idle` before the call it dispatched lands; the call
carries the interaction's frame but arrived after the claim window and
became a root span. It is now a child of the interaction's span by the same
identity, marked `solid.server_function.after_settle`.
Co-Authored-By: Claude via Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…hrough Playwright A Solid 2 app on @solidjs/vite-plugin's start mode with `observe: true`, the server SDK through `start.instrument`, the browser SDK from the app's client module, and a bare node:http host. Against the packed tarballs it proves what the units cannot: boundary and invocation spans under OTel's http.server span, the pageload continuing the server trace with no middleware, a click's server-function call becoming its child through a real fetch, and both error hooks firing once with component paths. Two findings folded into the README and the reviewer brief: a module both graphs reach must import the explicit client/server entry, and the app should declare @sentry/node so the plugin's inlining of this package does not bundle it too (import-in-the-middle cannot find itself from a bundle). Co-Authored-By: Claude via Cursor <cursoragent@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
…one host's preload Co-Authored-By: Claude via Cursor <cursoragent@cursor.com> Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A Sentry SDK for Solid 2 (
solid-js^2.0.0-rc.9). One package covers every Solid 2 project — client and server, any router, any host — because Solid 2 moved the things an SDK needs into the runtime itself. There is no SolidStart for Solid 2 and there is nothing in this package for a router or a host: the runtime has error hooks on both platforms, a structured observability channel (OBSERVE.records), an attribution engine that names the user interaction and the route behind every write (routers declare navigations to it withwithOrigin; the SDK never sees router code), and a server-side trace-context slot whose answer the runtime carries to the browser on its own (Server-Timing, the<meta>pair). So where@sentry/solidplus@sentry/solidstartneeded a router integration, a middleware to rewrite HTML, and a--importpreload per host, this is oneinit()on each side that subscribes.The server half's one requirement is
@sentry/node's, not Solid's:init()must run before the app's server graph loads so OpenTelemetry can patchnode:httpand friends. Each host does that its own way —node --import, a first import in a CJS entry; for apps served by@solidjs/vite-plugin's handler, itsstart.instrumentoption is that preload, since ESM hoisting defeats "import it first" there. The unit tests run the server integrations against barerenderToStreamwith no plugin involved; the e2e app is a plugin-hosted app because that is the reference deployment and it exercisesstart.instrument.Errors report in every Solid build tier through the two hooks, once per error object, with where it was thrown and where it was met. Tracing is opt-in and needs Solid's
observebuild (theobserveexport condition plus the compiler'scomponentNames;solid({ observe: true })sets both): one root span per user interaction with its navigations, holds and server-function calls as children (joined by the engine's object identity, not by time); server-function executions and waiting<Loading>boundaries as spans under OTel'shttp.server; the browserpageloadcontinuing the server trace with no middleware.Decisions worth a look: records set span status only and never capture — the same error reaches a hook, and Sentry's once-per-object guard made whichever ran first win (the e2e app caught the record misreporting a handled boundary catch as an unhandled crash). Element text from interaction targets is stripped unless
targetText: true. A call that lands after its interaction settled (onClick={async () => set(await call())}) is parented under the ended interaction span, markedafter_settle. Interactions are root spans rather than children of thepageloadidle span; open to changing that.The package name is a working one —
@sentry/solid-2vs. a new major of@sentry/solidstill needs a decision, and nothing in the code depends on it.docs/solid-2-observe.mdis the reviewer's brief on what the runtime exposes. The e2e app is marked optional until the CI matrix has run it.