apps/web: fix sentry trpc capture exception

This commit is contained in:
vchikalkin 2024-02-23 12:47:12 +03:00
parent e258873976
commit 557053caa6
12 changed files with 38 additions and 42 deletions

View File

@ -104,6 +104,5 @@ module.exports = withSentryConfig(
hideSourceMaps: true,
transpileClientSDK: false,
tunnelRoute: '/track-error',
widenClientFileUpload: true,
}
);

View File

@ -1,6 +1,6 @@
/* eslint-disable canonical/filename-match-regex */
import { Result } from 'ui/elements';
export default function ServerError() {
return <Result status="500" title="Ой" subTitle=" Что-то сломалось" />;
export default function ServerError({ statusCode = '500' }) {
return <Result status={statusCode} title="Ой" subTitle=" Что-то сломалось" />;
}

View File

@ -1,9 +1,10 @@
/* eslint-disable canonical/no-use-extend-native */
import ServerError from './500';
import { captureUnderscoreErrorException } from '@sentry/nextjs';
import Error from 'next/error';
function CustomErrorComponent(props) {
return <Error statusCode={props.statusCode} />;
return <ServerError statusCode={props.statusCode} />;
}
CustomErrorComponent.getInitialProps = async (contextData) => {

View File

@ -1,7 +1,6 @@
/* eslint-disable canonical/filename-match-regex */
import { createContext } from '@/server/context';
import { appRouter } from '@/server/routers/_app';
import { captureException, withScope } from '@sentry/nextjs';
import * as trpcNext from '@trpc/server/adapters/next';
export default trpcNext.createNextApiHandler({
@ -23,17 +22,7 @@ export default trpcNext.createNextApiHandler({
onError(opts) {
const { error } = opts;
// send to bug reporting
if (!['BAD_REQUEST', 'UNAUTHORIZED', 'FORBIDDEN'].includes(error.code))
withScope((scope) => {
(Object.keys(opts) as Array<keyof typeof opts>).forEach((key) => {
if (key !== 'req') {
let extra = opts[key];
if (key === 'input') extra = JSON.stringify(extra);
scope.setExtra(key, extra);
}
});
captureException(error);
});
// eslint-disable-next-line no-console
console.error('Something went wrong', error);
},

View File

@ -3,12 +3,18 @@
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
import getUrls from './config/urls';
import { publicRuntimeConfigSchema } from '@/config/schema/runtime-config';
import { init } from '@sentry/nextjs';
import getConfig from 'next/config';
const { SENTRY_DSN } = getUrls();
const { publicRuntimeConfig } = getConfig();
const { SENTRY_ENVIRONMENT } = publicRuntimeConfigSchema.parse(publicRuntimeConfig);
init({
debug: false,
dsn: SENTRY_DSN,
environment: SENTRY_ENVIRONMENT,
tracesSampleRate: 1,
});

View File

@ -3,13 +3,18 @@
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
import getUrls from './config/urls';
import { publicRuntimeConfigSchema } from '@/config/schema/runtime-config';
import { init } from '@sentry/nextjs';
import getConfig from 'next/config';
const { SENTRY_DSN } = getUrls();
const { publicRuntimeConfig } = getConfig();
const { SENTRY_ENVIRONMENT } = publicRuntimeConfigSchema.parse(publicRuntimeConfig);
init({
debug: false,
dsn: SENTRY_DSN,
environment: SENTRY_ENVIRONMENT,
tracesSampleRate: 1,
});

View File

@ -1,4 +1,5 @@
import { getUser } from '@/api/user/query';
import { getCurrentScope } from '@sentry/node';
import type { inferAsyncReturnType } from '@trpc/server';
import type { CreateNextContextOptions } from '@trpc/server/adapters/next';
@ -11,6 +12,9 @@ export async function createContext({ req }: CreateNextContextOptions) {
},
});
const scope = getCurrentScope();
scope.setUser(user);
return {
user,
};

View File

@ -1,5 +1,5 @@
/* eslint-disable canonical/sort-keys */
import { protectedProcedure, publicProcedure } from '../../procedure';
import { protectedProcedure } from '../../procedure';
import { router } from '../../trpc';
import { createRequestData } from '../calculate/lib/request';
import { transformCalculateResults } from '../calculate/lib/transform';
@ -54,7 +54,7 @@ const defaultPayments = { values: [], sums: [] };
const { URL_CRM_DOWNLOADKP } = getUrls();
export const quoteRouter = router({
getQuote: publicProcedure
getQuote: protectedProcedure
.input(GetQuoteInputDataSchema)
.output(GetQuoteOutputDataSchema)
.query(async ({ input }) => {

View File

@ -1,14 +1,19 @@
import { publicProcedure } from '../../procedure';
import { protectedProcedure } from '../../procedure';
import { router } from '../../trpc';
import { GetTarifInputSchema } from './types';
import initializeApollo from '@/apollo/client';
import configuratorHelper from '@/process/configurator/lib/helper';
import { createTRPCError } from '@/utils/trpc';
export const tarifRouter = router({
getTarif: publicProcedure.input(GetTarifInputSchema).query(async ({ input }) => {
const apolloClient = initializeApollo();
const { getTarifs } = configuratorHelper({ apolloClient });
getTarif: protectedProcedure.input(GetTarifInputSchema).query(async ({ input }) => {
try {
const apolloClient = initializeApollo();
const { getTarifs } = configuratorHelper({ apolloClient });
return getTarifs(input);
return getTarifs(input);
} catch (error) {
throw createTRPCError(error);
}
}),
});

View File

@ -11,7 +11,7 @@
import type { Context } from './context';
import { initTRPC } from '@trpc/server';
import SuperJSON from 'superjson';
import { SuperJSON } from 'superjson';
export const t = initTRPC.context<Context>().create({
/**

View File

@ -3,7 +3,7 @@ import type { AppRouter } from '@/server/routers/_app';
import { createTRPCProxyClient, httpBatchLink, loggerLink } from '@trpc/client';
import { createTRPCNext } from '@trpc/next';
import type { NextPageContext } from 'next';
import SuperJSON from 'superjson';
import { SuperJSON } from 'superjson';
import { isServer } from 'tools/common';
export type SSRContext = NextPageContext & {
@ -60,6 +60,7 @@ export const trpcClient = createTRPCNext<AppRouter>({
const {
// If you're using Node 18 before 18.15.0, omit the "connection" header
// eslint-disable-next-line @typescript-eslint/naming-convention, @typescript-eslint/no-unused-vars
connection: _connection,
...headers
} = ctx.req.headers;

View File

@ -1,8 +1,7 @@
import { HttpError } from './error';
import { captureException, withScope } from '@sentry/nextjs';
import { captureException } from '@sentry/nextjs';
import type { AxiosError } from 'axios';
import { isAxiosError } from 'axios';
import { pick } from 'radash';
function getErrorMessage<T extends { error?: string; errors?: string[]; message?: string }>(
error: AxiosError<T>
@ -21,22 +20,9 @@ export async function withHandleError<T>(fn: Promise<T>) {
const message = getErrorMessage(error_);
if (error_.response?.status && error_.response?.status >= 500) {
const err = pick(error_, ['code', 'message', 'status', 'cause']);
const data = error_.config?.data;
const params = error_.config?.params;
const opts = { ...err, data, message, params };
error_.message += ` | ${message}`;
withScope((scope) => {
(Object.keys(opts) as Array<keyof typeof opts>).forEach((key) => {
let extra = opts[key];
if (key === 'data') extra = JSON.stringify(extra);
scope.setExtra(key, extra);
});
captureException(error_);
});
captureException(error_);
}
throw new HttpError(message, error_.status || error_.response?.status);