More sentry monitoring

This commit is contained in:
2026-03-11 04:02:33 -04:00
parent 703510afa7
commit c2251ecfd4
7 changed files with 1633 additions and 1510 deletions

View File

@@ -2,16 +2,20 @@ import { CacheProvider } from "@emotion/react";
import { ClientStyleContext } from "./context.js";
import createEmotionCache from "./createEmotionCache.js";
import { hydrateRoot } from "react-dom/client";
import { RemixBrowser } from "@remix-run/react";
import * as Sentry from "@sentry/react";
import { type ReactNode, StrictMode, useState } from "react";
import { RemixBrowser, useLocation, useMatches } from "@remix-run/react";
import * as Sentry from "@sentry/remix";
import { type ReactNode, StrictMode, useEffect, useState } from "react";
Sentry.init({
dsn:
document.querySelector("meta[name='dsn']")?.getAttribute("content") ??
undefined,
integrations: [
Sentry.browserTracingIntegration(),
Sentry.browserTracingIntegration({
useEffect,
useLocation,
useMatches,
}),
Sentry.replayIntegration(),
],
replaysOnErrorSampleRate: 1,

View File

@@ -5,6 +5,7 @@ import { type EntryContext } from "@remix-run/cloudflare";
import { RemixServer } from "@remix-run/react";
import { renderToString } from "react-dom/server";
import { ServerStyleContext } from "./context.js";
import * as Sentry from "@sentry/remix";
export default function handleRequest(
request: Request,
@@ -39,3 +40,5 @@ export default function handleRequest(
status: responseStatusCode,
});
}
export const handleError = Sentry.sentryHandleError;

View File

@@ -18,6 +18,7 @@ import {
Scripts,
useLoaderData,
useRouteError,
useRouteLoaderData,
} from "@remix-run/react";
import { type ErrorResponse } from "@remix-run/router";
import { LinksFunction } from "@remix-run/cloudflare";
@@ -26,71 +27,85 @@ import Navigation from "../components/Navigation.js";
import { type ReactNode, StrictMode, useContext, useEffect } from "react";
import theme from "../theme.js";
import { withEmotionCache } from "@emotion/react";
import { captureRemixErrorBoundaryError, withSentry } from "@sentry/remix";
export function ErrorBoundary() {
const error = useRouteError() as ErrorResponse;
if (!isRouteErrorResponse(error))
return getMarkup(
{ hide: true },
<Container maxW="container.lg" pt="8vh" textAlign="left">
<Heading size="4xl">???</Heading>
<br />
<Text fontSize="xl">Something bad happened!</Text>
<br />
<br />
<br />
<Text>Details: {error}</Text>
<br />
<br />
<Link color="#646cff" onClick={() => location.reload()}>
Refresh
</Link>
</Container>,
return (
<DocumentWrapper loaderData={{ hide: true }}>
<Container maxW="container.lg" pt="8vh" textAlign="left">
<Heading size="4xl">???</Heading>
<br />
<Text fontSize="xl">Something bad happened!</Text>
<br />
<br />
<br />
<Text>Details: {error}</Text>
<br />
<br />
<Link color="#646cff" onClick={() => location.reload()}>
Refresh
</Link>
</Container>
</DocumentWrapper>
);
const { status } = error;
const loaderData = useRouteLoaderData<typeof loader>("root") || {};
switch (status) {
case 303:
return "";
case 401:
return getMarkup({ hide: true }, <Login />);
return (
<DocumentWrapper loaderData={loaderData}>
<Login />
</DocumentWrapper>
);
case 403:
return getMarkup({ hide: true }, <Forbidden />);
return (
<DocumentWrapper loaderData={loaderData}>
<Forbidden />
</DocumentWrapper>
);
case 404:
return getMarkup(
{ hide: true },
<Container maxW="container.lg" pt="8vh" textAlign="left">
<Heading size="4xl">404</Heading>
<br />
<Text fontSize="xl">There is nothing to find here.</Text>
<br />
<br />
<br />
<Link color="#646cff" onClick={() => history.go(-1)}>
Go back
</Link>
</Container>,
return (
<DocumentWrapper loaderData={loaderData}>
<Container maxW="container.lg" pt="8vh" textAlign="left">
<Heading size="4xl">404</Heading>
<br />
<Text fontSize="xl">There is nothing to find here.</Text>
<br />
<br />
<br />
<Link color="#646cff" onClick={() => history.go(-1)}>
Go back
</Link>
</Container>
</DocumentWrapper>
);
default:
return getMarkup(
{ hide: true },
<Container maxW="container.lg" pt="8vh" textAlign="left">
<Heading size="4xl">500</Heading>
<br />
<Text fontSize="xl">S̶̡͈̠̗̠͖͙̭o̶̶͕͚̥͍̪̤m̸̨͏͈͔̖͚̖̰̱͞e҉̵͖͚͇̀t̕͟͠͏͎̺̯̲̱̣̤̠̟͙̠̙̫̬ḩ̸̭͓̬͎̙̀į̞̮͉͖̰̥̹͚̫̙̪̗̜̳̕ͅn҉͔̯̪̗̝̝͖̲͇͍͎̲̲̤̖̫͈̪͡g̴̰̻̙̝͉̭͇̖̰̝̙͕̼͙͘͜ ̵̶̫̥̳̲̘̻̗͈͕̭̲͇̘̜̺̟̥̖̥b̴̙̭̹͕̞͠r̞͎̠̩͈̖̰̞̯̯͢͢͠ͅo̝̯̗̹̳͍̰͉͕̘̰̠̺̥̰͔̕ͅk̵̸̻̠͕̺̦̦͖̲̺̦̞̝̞͞͡e̶͏̤̼̼͔̘̰̰̭͈̀͞͡</Text>
<br />
<br />
<br />
<Link color="#646cff" onClick={() => location.reload()}>
Reload
</Link>
</Container>,
captureRemixErrorBoundaryError(useRouteError());
return (
<DocumentWrapper loaderData={loaderData}>
<Container maxW="container.lg" pt="8vh" textAlign="left">
<Heading size="4xl">500</Heading>
<br />
<Text fontSize="xl">S̶̡͈̠̗̠͖͙̭o̶̶͕͚̥͍̪̤m̸̨͏͈͔̖͚̖̰̱͞e҉̵͖͚͇̀t̕͟͠͏͎̺̯̲̱̣̤̠̟͙̠̙̫̬ḩ̸̭͓̬͎̙̀į̞̮͉͖̰̥̹͚̫̙̪̗̜̳̕ͅn҉͔̯̪̗̝̝͖̲͇͍͎̲̲̤̖̫͈̪͡g̴̰̻̙̝͉̭͇̖̰̝̙͕̼͙͘͜ ̵̶̫̥̳̲̘̻̗͈͕̭̲͇̘̜̺̟̥̖̥b̴̙̭̹͕̞͠r̞͎̠̩͈̖̰̞̯̯͢͢͠ͅo̝̯̗̹̳͍̰͉͕̘̰̠̺̥̰͔̕ͅk̵̸̻̠͕̺̦̦͖̲̺̦̞̝̞͞͡e̶͏̤̼̼͔̘̰̰̭͈̀͞͡</Text>
<br />
<br />
<br />
<Link color="#646cff" onClick={() => location.reload()}>
Reload
</Link>
</Container>
</DocumentWrapper>
);
}
}
@@ -123,10 +138,11 @@ export function meta() {
return [{ title: "Car Crushers" }];
}
function getMarkup(
loaderData: { [k: string]: any },
child: ReactNode,
): JSX.Element {
function DocumentWrapper(props: {
loaderData: { [k: string]: any };
children: ReactNode;
}) {
const { children: child, loaderData } = props;
const Document = withEmotionCache(
({ children }: { children: ReactNode }, emotionCache) => {
const serverStyleData = useContext(ServerStyleContext);
@@ -207,8 +223,14 @@ function getMarkup(
return <Document>{child}</Document>;
}
export default function () {
function App() {
const loaderData = useLoaderData<typeof loader>();
return getMarkup(loaderData, <Outlet />);
return (
<DocumentWrapper loaderData={loaderData}>
<Outlet />
</DocumentWrapper>
);
}
export default withSentry(App);