Skip to content

Commit

Permalink
POC Sentry
Browse files Browse the repository at this point in the history
Remove release & use getClientEnv

remove sourcemap from check build

pr fixes

add release to main_push workflow
  • Loading branch information
github-zoe-cade authored and Pascal-Delange committed Oct 25, 2023
1 parent 4a4375a commit d3b7c0a
Show file tree
Hide file tree
Showing 18 changed files with 303 additions and 39 deletions.
9 changes: 9 additions & 0 deletions .github/workflows/main_push.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ jobs:
actions: read
uses: ./.github/workflows/check.yaml

create_sentry_release:
uses: getsentry/action-release@v1
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: checkmarble
SENTRY_PROJECT: marble-frontend
with:
environment: production

build_and_deploy:
needs: check
permissions:
Expand Down
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,6 @@ Thumbs.db

# Firebase
firebase-debug.log
ui-debug.log
ui-debug.log
# Sentry Config File
.sentryclirc
3 changes: 1 addition & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ RUN pnpm install --prod --frozen-lockfile
FROM base AS build
# RUN --mount=type=cache,id=pnpm,target=$PNPM_HOME/store pnpm install --frozen-lockfile
RUN pnpm install --frozen-lockfile
RUN pnpm run -r build
RUN pnpm run -r build-with-sourcemaps

FROM base AS app-builder
ENV NODE_ENV=production
Expand All @@ -27,4 +27,3 @@ COPY --from=build /app/packages/app-builder/public /app/packages/app-builder/pub
WORKDIR /app/packages/app-builder
EXPOSE 8080
CMD [ "pnpm", "exec", "remix-serve", "build"]

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@
"@remix-run/node": "^1.19.3",
"@remix-run/react": "^1.19.3",
"@remix-run/serve": "^1.19.3",
"@sentry/cli": "^2.21.2",
"@sentry/remix": "^7.74.0",
"@tanstack/react-table": "^8.10.6",
"@tanstack/react-virtual": "3.0.0-beta.61",
"clsx": "^1.2.1",
Expand Down
7 changes: 6 additions & 1 deletion packages/app-builder/.env.local
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ SESSION_SECRET=SESSION_SECRET
SESSION_MAX_AGE=43200

MARBLE_API_DOMAIN=http://127.0.0.1:8080
MARBLE_APP_DOMAIN=http://127.0.0.1:3000

FIREBASE_AUTH_EMULATOR=true
FIREBASE_AUTH_EMULATOR_HOST=http://localhost:9099
Expand All @@ -14,4 +15,8 @@ FIREBASE_AUTH_DOMAIN=tokyo-country-381508.firebaseapp.com
FIREBASE_PROJECT_ID=tokyo-country-381508
FIREBASE_STORAGE_BUCKET=tokyo-country-381508.appspot.com
FIREBASE_MESSAGING_SENDER_ID=1047691849054
FIREBASE_APP_ID=1:1047691849054:web:a5b69dd2ac584c1160b3cf
FIREBASE_APP_ID=1:1047691849054:web:a5b69dd2ac584c1160b3cf

SENTRY_AUTH_TOKEN=dummy
SENTRY_DSN=dummy
SENTRY_ENVIRONMENT=development
1 change: 1 addition & 0 deletions packages/app-builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"type-check": "npx tsc --noEmit",
"dev": "dotenv -e .env.local -- remix dev",
"build": "remix build",
"build-with-sourcemaps": "remix build --sourcemap && sentry-upload-sourcemaps --org checkmarble --project marble-frontend",
"start": "remix start",
"generate-routes": "source scripts/generateRoutes.sh"
},
Expand Down
38 changes: 36 additions & 2 deletions packages/app-builder/src/entry.client.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { RemixBrowser } from '@remix-run/react';
import { startTransition, StrictMode } from 'react';
import { RemixBrowser, useLocation, useMatches } from '@remix-run/react';
import * as Sentry from '@sentry/remix';
import { startTransition, StrictMode, useEffect } from 'react';
import { hydrateRoot } from 'react-dom/client';
import { I18nextProvider } from 'react-i18next';

import { clientServices } from './services/init.client';
import { getClientEnv } from './utils/environment.client';

async function hydrate() {
const { i18nextClientService } = clientServices;
Expand All @@ -30,3 +32,35 @@ if (window.requestIdleCallback) {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
window.setTimeout(hydrate, 1);
}

Sentry.init({
dsn: getClientEnv('SENTRY_DSN'),
environment: getClientEnv('SENTRY_ENVIRONMENT'),
integrations: [
new Sentry.BrowserTracing({
routingInstrumentation: Sentry.remixRouterInstrumentation(
useEffect,
useLocation,
useMatches
),
}),
// Replay is only available in the client
new Sentry.Replay(),
],

// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for performance monitoring.
// We recommend adjusting this value in production
tracesSampleRate: 1.0,

// Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled
tracePropagationTargets: [
getClientEnv('MARBLE_APP_DOMAIN'),
getClientEnv('MARBLE_API_DOMAIN'),
],

// Capture Replay for 10% of all sessions,
// plus for 100% of sessions with an error
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
});
29 changes: 28 additions & 1 deletion packages/app-builder/src/entry.server.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import { type EntryContext, Response } from '@remix-run/node';
import {
type DataFunctionArgs,
type EntryContext,
Response,
} from '@remix-run/node';
import { RemixServer } from '@remix-run/react';
import * as Sentry from '@sentry/remix';
import isbot from 'isbot';
import { renderToPipeableStream } from 'react-dom/server';
import { I18nextProvider } from 'react-i18next';
import { PassThrough } from 'stream';

import { serverServices } from './services/init.server';
import { getServerEnv } from './utils/environment.server';

const ABORT_DELAY = 5000;

Expand Down Expand Up @@ -105,3 +111,24 @@ function handleBrowserRequest(
setTimeout(abort, ABORT_DELAY);
});
}

Sentry.init({
dsn: getServerEnv('SENTRY_DSN'),
environment: getServerEnv('SENTRY_ENVIRONMENT'),
// Set tracesSampleRate to 1.0 to capture 100%
// of transactions for performance monitoring.
// We recommend adjusting this value in production
tracesSampleRate: 1.0,
});

export async function handleError(
error: unknown,
{ request }: DataFunctionArgs
) {
if (error instanceof Error) {
await Sentry.captureRemixServerException(error, 'remix.server', request);
} else {
// Optionally capture non-Error objects
Sentry.captureException(error);
}
}
6 changes: 5 additions & 1 deletion packages/app-builder/src/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
useLoaderData,
useRouteError,
} from '@remix-run/react';
import { captureRemixErrorBoundaryError, withSentry } from '@sentry/remix';
import { Tooltip } from '@ui-design-system';
import { LogoStandard } from '@ui-icons';
import { type Namespace } from 'i18next';
Expand Down Expand Up @@ -101,6 +102,7 @@ export const meta: V2_MetaFunction = () => [

export function ErrorBoundary() {
const error = useRouteError();
captureRemixErrorBoundaryError(error);

return (
<html lang="en">
Expand Down Expand Up @@ -135,7 +137,7 @@ export function ErrorBoundary() {
);
}

export default function App() {
function App() {
const { locale, ENV, toastMessage, csrf } = useLoaderData<typeof loader>();

const { i18n } = useTranslation(handle.i18n);
Expand Down Expand Up @@ -169,3 +171,5 @@ export default function App() {
</html>
);
}

export default withSentry(App);
6 changes: 5 additions & 1 deletion packages/app-builder/src/routes/__builder/decisions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
import { DecisionsPage } from '@app-builder/components/Decisions';
import { getRoute } from '@app-builder/utils/routes';
import { Outlet, useRouteError } from '@remix-run/react';
import { captureRemixErrorBoundaryError } from '@sentry/remix';
import { Decision } from '@ui-icons';
import { type Namespace } from 'i18next';
import { useTranslation } from 'react-i18next';
Expand Down Expand Up @@ -52,5 +53,8 @@ export default function DecisionsLayout() {
}

export function ErrorBoundary() {
return <ErrorComponent error={useRouteError()} />;
const error = useRouteError();
captureRemixErrorBoundaryError(error);

return <ErrorComponent error={error} />;
}
6 changes: 4 additions & 2 deletions packages/app-builder/src/routes/__builder/lists/$listId.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { serverServices } from '@app-builder/services/init.server';
import { fromParams } from '@app-builder/utils/short-uuid';
import { json, type LoaderArgs } from '@remix-run/node';
import { Link, useLoaderData, useRouteError } from '@remix-run/react';
import { captureRemixErrorBoundaryError } from '@sentry/remix';
import {
type ColumnDef,
getCoreRowModel,
Expand Down Expand Up @@ -151,9 +152,10 @@ export default function Lists() {
</Page.Container>
);
}

export function ErrorBoundary() {
return <ErrorComponent error={useRouteError()} />;
const error = useRouteError();
captureRemixErrorBoundaryError(error);
return <ErrorComponent error={error} />;
}

// Correspond to this part of the UI : https://www.figma.com/file/JW6QvnhBtdZDcKvLdg9s5T/Marble-Portal?node-id=6377%3A53150&mode=dev
Expand Down
6 changes: 4 additions & 2 deletions packages/app-builder/src/routes/__builder/lists/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { getRoute } from '@app-builder/utils/routes';
import { fromUUID } from '@app-builder/utils/short-uuid';
import { json, type LoaderArgs } from '@remix-run/node';
import { useLoaderData, useNavigate, useRouteError } from '@remix-run/react';
import { captureRemixErrorBoundaryError } from '@sentry/remix';
import {
type ColumnDef,
getCoreRowModel,
Expand Down Expand Up @@ -114,7 +115,8 @@ export default function ListsPage() {
</Page.Container>
);
}

export function ErrorBoundary() {
return <ErrorComponent error={useRouteError()} />;
const error = useRouteError();
captureRemixErrorBoundaryError(error);
return <ErrorComponent error={error} />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { serverServices } from '@app-builder/services/init.server';
import { fromParams } from '@app-builder/utils/short-uuid';
import { json, type LoaderArgs, type SerializeFrom } from '@remix-run/node';
import { Outlet, useRouteError, useRouteLoaderData } from '@remix-run/react';
import { captureRemixErrorBoundaryError } from '@sentry/remix';
import { type Namespace } from 'i18next';

export const handle = {
Expand Down Expand Up @@ -30,7 +31,8 @@ export const useCurrentScenario = () =>
export default function CurrentScenarioProvider() {
return <Outlet />;
}

export function ErrorBoundary() {
return <ErrorComponent error={useRouteError()} />;
const error = useRouteError();
captureRemixErrorBoundaryError(error);
return <ErrorComponent error={error} />;
}
28 changes: 28 additions & 0 deletions packages/app-builder/src/routes/sentry.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useFetcher } from '@remix-run/react';
import { Button } from '@ui-design-system';

export function loader() {
return 'ok';
}

export function action() {
throw new Error('This is an error from an action');
}

export default function Sentry() {
const fetcher = useFetcher<typeof action>();
const iStillDoNotExist = () => {
throw new Error('This is an error from a component');
};
return (
<div>
<h1>Test Sentry</h1>
<Button onClick={() => iStillDoNotExist()}>
Crash the app from the browser
</Button>
<fetcher.Form method="POST" action="/sentry">
<Button type="submit">Crash the app with a server error</Button>
</fetcher.Form>
</div>
);
}
3 changes: 3 additions & 0 deletions packages/app-builder/src/utils/environment.client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ export type ClientEnvVars = {
AUTH_EMULATOR_HOST?: string;
FIREBASE_OPTIONS: FirebaseOptions;
MARBLE_API_DOMAIN: string;
MARBLE_APP_DOMAIN: string;
SENTRY_DSN: string;
SENTRY_ENVIRONMENT: string;
};

export function getClientEnv<K extends keyof ClientEnvVars>(
Expand Down
7 changes: 7 additions & 0 deletions packages/app-builder/src/utils/environment.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,11 @@ type ServerPublicEnvVarName =
| 'FIREBASE_PROJECT_ID'
| 'FIREBASE_STORAGE_BUCKET'
| 'MARBLE_API_DOMAIN'
| 'MARBLE_APP_DOMAIN'
| 'NODE_ENV'
| 'SENTRY_AUTH_TOKEN'
| 'SENTRY_DSN'
| 'SENTRY_ENVIRONMENT'
| 'SESSION_MAX_AGE';

/**
Expand Down Expand Up @@ -84,5 +88,8 @@ export function getClientEnvVars(): ClientEnvVars {
appId: getServerEnv('FIREBASE_APP_ID'),
},
MARBLE_API_DOMAIN: getServerEnv('MARBLE_API_DOMAIN'),
MARBLE_APP_DOMAIN: getServerEnv('MARBLE_APP_DOMAIN'),
SENTRY_DSN: getServerEnv('SENTRY_DSN'),
SENTRY_ENVIRONMENT: getServerEnv('SENTRY_ENVIRONMENT'),
};
}
5 changes: 5 additions & 0 deletions packages/app-builder/src/utils/routes/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ export const routes = [
}
]
},
{
"id": "routes/sentry",
"path": "sentry",
"file": "routes/sentry.tsx"
},
{
"id": "routes/index",
"index": true,
Expand Down
Loading

0 comments on commit d3b7c0a

Please sign in to comment.