Skip to content

Commit

Permalink
프로덕션 에러 추적 개선을 위한 Sentry 환경 구축 (#770)
Browse files Browse the repository at this point in the history
  • Loading branch information
dladncks1217 authored and hgo641 committed Apr 23, 2024
1 parent 503c591 commit 31f8d35
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 0 deletions.
182 changes: 182 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@googlemaps/react-wrapper": "^1.1.35",
"@sentry/react": "^7.89.0",
"@tanstack/react-query": "^5.13.4",
"assert": "^2.1.0",
"axios": "^1.4.0",
Expand Down
12 changes: 12 additions & 0 deletions frontend/src/api/interceptors.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as Sentry from '@sentry/react';

import type { AxiosError, InternalAxiosRequestConfig } from 'axios';

import { HTTPError } from '@api/HTTPError';
Expand Down Expand Up @@ -30,6 +32,11 @@ export const checkAndSetToken = (config: InternalAxiosRequestConfig) => {
};

export const handleTokenError = async (error: AxiosError<ErrorResponseData>) => {
Sentry.withScope((scope) => {
scope.setLevel('error');
Sentry.captureMessage(`[TokenError] ${window.location.href} \n ${error.response?.data}`);
});

const originalRequest = error.config;

if (!error.response || !originalRequest) throw new Error('에러가 발생했습니다.');
Expand Down Expand Up @@ -64,6 +71,11 @@ export const handleTokenError = async (error: AxiosError<ErrorResponseData>) =>
};

export const handleAPIError = (error: AxiosError<ErrorResponseData>) => {
Sentry.withScope((scope) => {
scope.setLevel('error');
Sentry.captureMessage(`[APIError] ${window.location.href} \n ${error.response?.data}`);
});

if (!error.response) throw error;

const { data, status } = error.response;
Expand Down
17 changes: 17 additions & 0 deletions frontend/src/components/common/Error/Error.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import * as Sentry from '@sentry/react';

import { useEffect } from 'react';

import { useRecoilValue } from 'recoil';

import axios from 'axios';

import { Box, Button, Flex, Heading, Text } from 'hang-log-design-system';

import {
Expand Down Expand Up @@ -33,6 +39,17 @@ const Error = ({ statusCode = HTTP_STATUS_CODE.NOT_FOUND, errorCode, resetError

const { handleTokenError } = useTokenError();

useEffect(() => {
if (statusCode === HTTP_STATUS_CODE.NOT_FOUND) {
axios.get('https://geolocation-db.com/json/').then((res) => {
Sentry.withScope((scope) => {
scope.setLevel('warning');
Sentry.captureMessage(`[Warning] ${window.location.href} from ${res.data.IPv4}`);
});
});
}
}, [statusCode]);

if (!isHTTPError) return null;

if (errorCode && errorCode > ERROR_CODE.TOKEN_ERROR_RANGE) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as Sentry from '@sentry/react';

import type { ComponentType, PropsWithChildren } from 'react';
import { Component } from 'react';

Expand Down Expand Up @@ -27,6 +29,13 @@ class ErrorBoundary extends Component<PropsWithChildren<ErrorBoundaryProps>, Sta
return { hasError: true, error };
}

componentDidCatch(error: Error | HTTPError): void {
Sentry.withScope((scope) => {
scope.setLevel('error');
Sentry.captureMessage(`[${error.name}] ${window.location.href}`);
});
}

resetErrorBoundary = () => {
const { onReset } = this.props;
const { error } = this.state;
Expand Down
17 changes: 17 additions & 0 deletions frontend/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Global } from '@emotion/react';
import * as Sentry from '@sentry/react';

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
Expand All @@ -21,6 +22,8 @@ import { GlobalStyle } from '@styles/index';
import { worker } from '@mocks/browser';

const main = async () => {
const tracePropagationTargets: (RegExp | string)[] = [/^https:\/\/hanglog\.(com|site)/];

if (process.env.NODE_ENV === 'development') {
await worker.start({
serviceWorker: {
Expand All @@ -30,6 +33,20 @@ const main = async () => {
});
}

Sentry.init({
dsn: process.env.SENTRY_DSN,
integrations: [
new Sentry.BrowserTracing({
tracePropagationTargets,
}),
new Sentry.Replay(),
],

tracesSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
});

const root = createRoot(document.querySelector('#root') as Element);

root.render(
Expand Down

0 comments on commit 31f8d35

Please sign in to comment.