SolidJS brings a distinctly reactive approach to building web applications, but error handling requires a different mental model than you might be used to from React. Unlike React's class-based error boundaries, SolidJS offers catchError and ErrorBoundary patterns that align with its signals-based architecture. Understanding SolidJS error boundary implementation monitoring is essential if you want to catch production failures and debug them before users report them hours later.
The challenge isn't just catching errors—it's catching them in the right place, at the right time, within Solid's reactive model. A stray error in a computation can silently fail or cascade through effects in ways that are hard to reason about. Adding production error tracking transforms this into a systematic process: errors are captured, enriched with context, and delivered to your dashboard for triage.
Why SolidJS Error Tracking Matters
Errors in production are a certainty. A failed API call, a race condition, or a malformed data payload will happen in your users' environments. Without visibility, you're debugging in the dark. SolidJS's fine-grained reactivity is powerful, but it also means errors can propagate in less obvious ways than in larger-grained frameworks.
Error tracking for SolidJS serves a few core purposes:
- Visibility: Know when errors occur in production, not just during development.
- Context: Capture stack traces, user info, affected routes, and release metadata alongside each error.
- Triage: Group errors by fingerprint so you see actual issues, not just raw events.
- Speed: Learn how to debug production errors faster with source maps and stack trace de-symbolication.
Unlike server-side rendering error tracking, client-side SolidJS errors are often UI state mismatches, async race conditions, or third-party script failures. You need a tool built for that.
SolidJS errors in effects and computed properties can be tricky: they don't always throw synchronously. Wrapping them in a robust error boundary and forwarding to an error tracker is the professional approach.
SolidJS Error Boundaries and Error Handling Patterns
SolidJS has two main patterns for error containment: ErrorBoundary components and the catchError utility.
ErrorBoundary is a component that catches errors thrown during rendering or in effects within its children. It's similar to React's error boundary but works with Solid's reactivity model:
import { ErrorBoundary } from "solid-js";
export function App() {
return (
<ErrorBoundary
fallback={(err, reset) => (
<div>
<p>Something went wrong: {err.message}</p>
<button onClick={reset}>Retry</button>
</div>
)}
>
<YourApp />
</ErrorBoundary>
);
}
catchError is a utility for catching errors inside effects or computations:
import { catchError, createEffect } from "solid-js";
export function MyComponent() {
createEffect(
catchError(
() => {
// Your reactive code here
fetch("/api/data").then(r => r.json());
},
(err) => {
console.error("Caught:", err);
// Handle or re-throw
}
)
);
return <div>Component</div>;
}
Both patterns allow you to intercept errors before they bubble up or silently fail. The key difference from React: errors don't necessarily throw; they can occur asynchronously within a reactive graph. You must be explicit about where you want to catch them.
Integrating LightTrace Error Tracking
Once you've structured error handling with ErrorBoundary and catchError, the next step is sending those errors to LightTrace so you can monitor them in production.
Start by installing the Sentry SDK (LightTrace is Sentry-compatible, so any Sentry SDK works out of the box):
npm install @sentry/browser
Initialize it early in your app, before any other code runs:
import * as Sentry from "@sentry/browser";
import { render } from "solid-js/web";
Sentry.init({
dsn: "https://<key>@light-trace.robomiri.com/1",
environment: "production",
release: "1.0.0",
tracesSampleRate: 0.1, // 10% of transactions
});
render(() => <App />, document.getElementById("app"));
Now integrate it with your ErrorBoundary:
import * as Sentry from "@sentry/browser";
import { ErrorBoundary } from "solid-js";
export function App() {
return (
<ErrorBoundary
fallback={(err, reset) => {
// Capture the error in LightTrace
Sentry.captureException(err, {
tags: { component: "AppBoundary" },
contexts: {
reactive: {
boundary: "root",
},
},
});
return (
<div>
<h2>Something went wrong</h2>
<p>{err.message}</p>
<button onClick={reset}>Try again</button>
</div>
);
}}
>
<YourApp />
</ErrorBoundary>
);
}
And wrap catchError blocks to report to LightTrace:
createEffect(
catchError(
() => {
// Reactive code
},
(err) => {
Sentry.captureException(err, {
tags: { effect: "myEffect" },
level: "warning",
});
}
)
);
By tagging errors with their source (component, effect, route), you make it much easier to group and triage them later.
Capturing User and Request Context
Raw stack traces are useful, but they're most powerful when paired with context. LightTrace captures user identity, HTTP headers, and request info automatically for you. You can add custom context to enrich errors:
import * as Sentry from "@sentry/browser";
// Set current user
Sentry.setUser({
id: userId,
email: userEmail,
});
// Add breadcrumbs for debugging
Sentry.addBreadcrumb({
category: "navigation",
message: `Navigated to ${newRoute}`,
level: "info",
});
// Add custom context
Sentry.setContext("request", {
endpoint: "/api/users",
method: "GET",
status: 500,
});
In SolidJS, you often do this inside effects. For example, when the user ID signal changes:
createEffect(() => {
const uid = userId(); // reactive dependency
if (uid) {
Sentry.setUser({ id: uid });
}
});
This ensures that all subsequent errors are attributed to the correct user, making it easy to see who was affected when you're diagnosing an issue.
Use breadcrumbs liberally in high-traffic flows (form submissions, API calls, navigation). They're the breadcrumb trail that leads you to root cause.
Handling Async Errors in Effects and Resources
One of SolidJS's strengths is its createResource primitive for async data fetching. Errors in resource fetchers don't automatically propagate to an ErrorBoundary—you need to handle them explicitly.
import { createResource } from "solid-js";
import * as Sentry from "@sentry/browser";
function UserDetails(props) {
const [user] = createResource(
() => props.userId,
async (userId) => {
try {
const res = await fetch(`/api/users/${userId}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
} catch (err) {
Sentry.captureException(err, {
tags: { resource: "user" },
contexts: { params: { userId } },
});
throw err; // Re-throw to let ErrorBoundary catch it
}
}
);
return (
<Show
when={user()}
fallback={<p>Loading...</p>}
>
<div>{user().name}</div>
</Show>
);
}
By catching and logging within the fetcher, you get early visibility. Re-throwing ensures the error bubbles up to your component's error boundary, so the UI can respond gracefully.
Source Maps and Stack Trace Symbolication
Minified production code produces stack traces with unhelpful filenames and line numbers. LightTrace automatically applies source maps if you upload them, turning d.A (app.min.js:1:50000) into fetchUser (userService.ts:42).
To upload source maps during your build:
# Install the Sentry CLI
npm install --save-dev @sentry/cli
# Build your app
npm run build
# Upload source maps
sentry-cli releases files upload-sourcemaps dist/
Configure this in your build pipeline so every deployment automatically sends source maps to LightTrace. This alone can cut debugging time in half—instead of staring at minified code, you see your actual source.
Source maps can contain sensitive code. Use LightTrace's PII scrubbing settings and only upload production source maps to a secure server. Never commit them to version control.
Monitoring Error Trends and Alerting
What is error tracking beyond just seeing each error as it happens? It's also spotting trends. LightTrace groups errors by fingerprint and shows you how many users were affected, when the issue started, and which releases introduced it.
Set up alert rules so you're notified when something goes wrong. For example:
- New issue alert: Notify your team the first time an error fingerprint is seen.
- Event frequency alert: Alert if an existing issue suddenly gets 10+ events in 5 minutes (possible outage).
Pair that with release tracking: tag your deployments so you can correlate errors with code changes.
// On deploy
Sentry.captureMessage("Deployed version 1.0.5", "info");
Over time, you'll see which releases were stable and which introduced regressions. This is how to debug production errors systematically—not just reacting to crashes, but learning from patterns.
Differences from add-error-tracking-to-your-app in Other Frameworks
SolidJS error tracking shares the same core principles as error tracking in React or Vue, but the execution is different. SolidJS's reactive model means:
- Errors in effects and computed values are not always synchronous.
ErrorBoundaryworks on a component subtree, but reactive graphs can span multiple components.catchErroris more granular and flexible than class-based error boundaries.
The setup and LightTrace integration remain the same: initialize once, set context, tag errors, upload source maps, and monitor. The main difference is being intentional about where errors can occur in a reactive system.
Error tracking in SolidJS is about understanding where errors hide and giving yourself visibility into production. By combining ErrorBoundary, catchError, and a robust error tracker like LightTrace, you transform crashes from mysterious bugs into actionable data. Your team stops flying blind, and your users get a more stable product.
Start tracking errors in minutes
Start tracking SolidJS errors today—sign up for a free LightTrace account and integrate the Sentry SDK in minutes.