Skip to content

Commit a1c5ee6

Browse files
feat(skills-next): add react-router-framework SDK references (#250)
1 parent f8e4ad4 commit a1c5ee6

8 files changed

Lines changed: 987 additions & 0 deletions

File tree

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Error Monitoring — Sentry React Router Framework SDK
2+
3+
> Minimum SDK: `@sentry/react-router` (beta)
4+
5+
---
6+
7+
## Automatic and Manual Capture
8+
9+
| Area | Auto Captured? | Mechanism |
10+
|------|----------------|-----------|
11+
| Client-side framework errors | ✅ Yes | `HydratedRouter onError={Sentry.sentryOnError}` |
12+
| Unhandled client exceptions | ✅ Yes | Browser global handlers from SDK init |
13+
| Server request/render errors | ✅ Yes | `createSentryHandleRequest` + `createSentryHandleError` |
14+
| Custom handled server errors | ❌ Not always | Call `Sentry.captureException` manually |
15+
| Custom loader/action failures | ⚠️ Depends | Use `wrapServerLoader` / `wrapServerAction` or manual capture |
16+
17+
---
18+
19+
## Client setup requirement
20+
21+
`entry.client.tsx` must include:
22+
23+
```tsx
24+
import * as Sentry from "@sentry/react-router";
25+
import { HydratedRouter } from "react-router/dom";
26+
27+
Sentry.init({
28+
dsn: "___PUBLIC_DSN___",
29+
});
30+
31+
hydrateRoot(document, <HydratedRouter onError={Sentry.sentryOnError} />);
32+
```
33+
34+
Without `sentryOnError`, framework-level client errors may be missed.
35+
36+
---
37+
38+
## Server setup requirement
39+
40+
`entry.server.tsx`:
41+
42+
```tsx
43+
import * as Sentry from "@sentry/react-router";
44+
import { createReadableStreamFromReadable } from "@react-router/node";
45+
import { renderToPipeableStream } from "react-dom/server";
46+
import { ServerRouter } from "react-router";
47+
48+
const handleRequest = Sentry.createSentryHandleRequest({
49+
ServerRouter,
50+
renderToPipeableStream,
51+
createReadableStreamFromReadable,
52+
});
53+
54+
export default handleRequest;
55+
56+
export const handleError = Sentry.createSentryHandleError({
57+
logErrors: false,
58+
});
59+
```
60+
61+
---
62+
63+
## Manual capture in custom handlers
64+
65+
```tsx
66+
import * as Sentry from "@sentry/react-router";
67+
68+
export function handleError(error: unknown, args: unknown) {
69+
Sentry.captureException(error);
70+
console.error(error);
71+
}
72+
```
73+
74+
For custom streaming request implementations, wrap your handler:
75+
76+
```tsx
77+
import { wrapSentryHandleRequest } from "@sentry/react-router";
78+
79+
export default wrapSentryHandleRequest(customHandleRequest);
80+
```
81+
82+
---
83+
84+
## Loader/action wrappers
85+
86+
```ts
87+
import * as Sentry from "@sentry/react-router";
88+
89+
export const loader = Sentry.wrapServerLoader(
90+
{ name: "Load Data", description: "Loads route data" },
91+
async () => {
92+
// loader logic
93+
},
94+
);
95+
96+
export const action = Sentry.wrapServerAction(
97+
{ name: "Submit Data", description: "Handles form submission" },
98+
async () => {
99+
// action logic
100+
},
101+
);
102+
```
103+
104+
---
105+
106+
## Verification
107+
108+
Use a route loader that throws:
109+
110+
```tsx
111+
export async function loader() {
112+
throw new Error("My first Sentry error!");
113+
}
114+
```
115+
116+
Open the route and verify the event appears in **Issues**.
117+
118+
---
119+
120+
## Troubleshooting
121+
122+
| Issue | Solution |
123+
|-------|----------|
124+
| Client framework errors missing | Ensure `HydratedRouter` uses `onError={Sentry.sentryOnError}` |
125+
| Server render/request errors missing | Verify both `createSentryHandleRequest` and `createSentryHandleError` are exported |
126+
| Custom handlers not captured | Add explicit `captureException` calls |
127+
| Error appears locally but not in Sentry | Check DSN, network restrictions, and `debug: true` output |

0 commit comments

Comments
 (0)