Skip to content

Commit aceda5d

Browse files
authored
Merge pull request #285 from waldo-vision/build(web)-sentry-cleanup
2 parents d30e96c + 4c44df6 commit aceda5d

File tree

7 files changed

+73
-155
lines changed

7 files changed

+73
-155
lines changed

apps/web/package.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
"@marsidev/react-turnstile": "0.1.2",
2222
"@next-auth/prisma-adapter": "^1.0.5",
2323
"@sentry/integrations": "^7.48.0",
24-
"@sentry/nextjs": "^7.44.1",
25-
"@sentry/node": "^7.48.0",
24+
"@sentry/nextjs": "^7.48.0",
2625
"@sentry/profiling-node": "^0.3.0",
2726
"@tanstack/query-core": "^4.20.4",
2827
"@tanstack/react-query": "^4.28.0",

apps/web/pages/api/auth/[...nextauth].ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,20 @@ export const authOptions = {
6767
],
6868
callbacks: {
6969
async session(sessionCallback: SessionCallback) {
70+
// create a span to track the time it takes to run this callback
71+
const span = Sentry.getCurrentHub()
72+
.getScope()
73+
.getTransaction()
74+
?.startChild({
75+
op: 'nextauth.session',
76+
});
77+
7078
const session = sessionCallback.session;
7179
const user = sessionCallback.user;
80+
81+
// set the user on the sentry scope
82+
Sentry.getCurrentHub().getScope().setUser({ id: user.id });
83+
7284
if (session.user) {
7385
session.user.id = user.id;
7486
if (user) {
@@ -86,13 +98,27 @@ export const authOptions = {
8698
session.user.blacklisted = userAccount?.user.blacklisted as boolean;
8799
}
88100
}
101+
span?.finish();
89102
return session;
90103
},
91104
async redirect(redirectCallback: RedirectCallback) {
92105
// redirects to home page instead of auth page on signup/in/ or logout.
93106
return redirectCallback.baseUrl;
94107
},
95108
async signIn(signInCallback: signInCallback) {
109+
// create a span to track the time it takes to run this callback
110+
const span = Sentry.getCurrentHub()
111+
.getScope()
112+
.getTransaction()
113+
?.startChild({
114+
op: 'nextauth.signIn',
115+
});
116+
117+
// set the user id to the current span
118+
Sentry.getCurrentHub()
119+
.getScope()
120+
.setUser({ id: signInCallback.account?.userId });
121+
96122
if (signInCallback.account?.provider === 'github') {
97123
if (
98124
signInCallback.account.providerAccountId == RicanGHId ||
@@ -124,10 +150,13 @@ export const authOptions = {
124150
// return true here even if error because account does not exist...
125151
// but still allow user otherwise they would never be able to sign in
126152
return true;
153+
} finally {
154+
span?.finish();
127155
}
128156
return true;
129157
}
130158
}
159+
span?.finish();
131160
return true;
132161
},
133162
},

apps/web/server/db/client.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as Sentry from '@sentry/node';
1+
import * as Sentry from '@sentry/nextjs';
22
import { PrismaClient } from 'database';
33

44
declare global {

apps/web/server/trpc/router/gameplay.ts

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,8 @@ export const gameplayRouter = router({
154154
)
155155
.output(GameplaySchema)
156156
.mutation(async ({ input, ctx }) => {
157-
const transaction = Sentry.startTransaction({
158-
op: 'createGameplay',
159-
name: 'Create a new gameplay',
160-
});
161-
162157
const isPerson = await vUser(input.tsToken);
163158
if (!isPerson) {
164-
transaction.finish();
165159
throw new TRPCError({
166160
code: 'BAD_REQUEST',
167161
message:
@@ -178,7 +172,6 @@ export const gameplayRouter = router({
178172

179173
// this needs to be handled client side
180174
if (existingGameplay !== null) {
181-
transaction.finish();
182175
throw new TRPCError({
183176
code: 'BAD_REQUEST',
184177
message: 'This youtube url has already been submitted.',
@@ -189,7 +182,6 @@ export const gameplayRouter = router({
189182
/^(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
190183

191184
if (!input.youtubeUrl.match(isValid)) {
192-
transaction.finish();
193185
throw new TRPCError({
194186
code: 'BAD_REQUEST',
195187
message: 'This url does not seem to be from youtube.',
@@ -222,10 +214,8 @@ export const gameplayRouter = router({
222214
cheats: input.cheats,
223215
},
224216
});
225-
transaction.finish();
226217
return data;
227218
} catch (error) {
228-
transaction.finish();
229219
Sentry.captureException(error);
230220
throw new TRPCError({
231221
code: 'INTERNAL_SERVER_ERROR',
@@ -475,10 +465,6 @@ export const gameplayRouter = router({
475465
)
476466
.output(ReviewItemsGameplaySchema)
477467
.query(async ({ input, ctx }) => {
478-
const transaction = Sentry.startTransaction({
479-
op: 'getReviewItems',
480-
name: 'Get Review Items',
481-
});
482468
const itemCount = await ctx.prisma.gameplay.count();
483469
const reviewItem = await ctx.prisma.gameplay.findMany({
484470
where: {
@@ -507,7 +493,6 @@ export const gameplayRouter = router({
507493
},
508494
});
509495
if (reviewItem[0] == null || reviewItem[0] == undefined) {
510-
transaction.finish();
511496
throw new TRPCError({ code: 'NOT_FOUND' });
512497
} else {
513498
Object.assign(reviewItem[0], {
@@ -518,7 +503,6 @@ export const gameplayRouter = router({
518503
},
519504
});
520505
Object.assign(reviewItem[0], { total: itemCount });
521-
transaction.finish();
522506
return reviewItem[0] as ReviewItemOutput;
523507
}
524508
}),
@@ -534,13 +518,8 @@ export const gameplayRouter = router({
534518
)
535519
.output(z.object({ message: z.string() }))
536520
.mutation(async ({ input, ctx }) => {
537-
const transaction = Sentry.startTransaction({
538-
op: 'review',
539-
name: 'Review',
540-
});
541521
const isPerson = await vUser(input.tsToken);
542522
if (!isPerson) {
543-
transaction.finish();
544523
throw new TRPCError({
545524
code: 'BAD_REQUEST',
546525
message:
@@ -558,14 +537,11 @@ export const gameplayRouter = router({
558537
},
559538
});
560539
if (!footageVote) {
561-
transaction.finish();
562540
throw new TRPCError({
563541
code: 'NOT_FOUND',
564542
message: `Could not find a gameplay document with id:${input.gameplayId}.`,
565543
});
566544
}
567-
568-
transaction.finish();
569545
return { message: 'Updated the gameplay document successfully.' };
570546
}),
571547
});

apps/web/server/trpc/router/site.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,18 @@ export const siteRouter = router({
3030
}),
3131
)
3232
.query(async ({ input, ctx }) => {
33-
const transaction = Sentry.startTransaction({
34-
op: 'getPageData',
35-
name: 'Get Page Data',
36-
});
3733
const pageData = await ctx.prisma.waldoPage.findFirst({
3834
where: {
3935
name: input.name,
4036
},
4137
});
4238
if (pageData == null) {
43-
transaction.finish();
4439
throw new TRPCError({
4540
code: 'NOT_FOUND',
4641
message: 'Waldo Vision Page not found in the database.',
4742
});
4843
}
4944
// no error checking because the docs will never be deleted.
50-
transaction.finish();
5145
return pageData;
5246
}),
5347
getSiteData: publicProcedure
@@ -73,10 +67,6 @@ export const siteRouter = router({
7367
}),
7468
)
7569
.query(async ({ input, ctx }) => {
76-
const transaction = Sentry.startTransaction({
77-
op: 'getSiteData',
78-
name: 'Get Site Data',
79-
});
8070
const siteData = await ctx.prisma.waldoSite.findUnique({
8171
where: {
8272
name: input.siteName,
@@ -88,7 +78,6 @@ export const siteRouter = router({
8878
message: 'Waldo Vision Page not found in the database.',
8979
});
9080
}
91-
transaction.finish();
9281
return siteData;
9382
}),
9483
updatePage: protectedProcedure

apps/web/server/trpc/trpc.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { OpenApiMeta } from 'trpc-openapi';
44
import { type Context } from './context';
55
import { compareKeyAgainstHash } from '@server/utils/apiHelper';
66
// import * as Sentry from '@sentry/nextjs';
7-
import * as Sentry from '@sentry/node';
7+
import * as Sentry from '@sentry/nextjs';
88

99
const t = initTRPC
1010
.context<Context>()
@@ -18,6 +18,7 @@ const t = initTRPC
1818

1919
export const router = t.router;
2020

21+
// create a sentry transaction/span for each endpoint
2122
const sentryMiddleware = t.middleware(
2223
Sentry.Handlers.trpcMiddleware({
2324
attachRpcInput: true,
@@ -40,7 +41,9 @@ const isAuthed = t.middleware(async ({ ctx, next }) => {
4041

4142
if (ctx.session.user.blacklisted) throw new TRPCError({ code: 'FORBIDDEN' });
4243

43-
Sentry.setUser({ id: ctx.session.user.id });
44+
// set the user on the sentry scope
45+
// so we can track effected users
46+
Sentry.getCurrentHub().getScope().setUser({ id: ctx.session.user.id });
4447

4548
return next({
4649
ctx: {
@@ -110,7 +113,7 @@ const isApiAuthed = t.middleware(async ({ ctx, next }) => {
110113
});
111114
});
112115

113-
export const apiProcedure = t.procedure.use(isApiAuthed);
116+
export const apiProcedure = t.procedure.use(sentryMiddleware).use(isApiAuthed);
114117

115118
export const protectedProcedure = t.procedure
116119
.use(sentryMiddleware)

0 commit comments

Comments
 (0)