-
Notifications
You must be signed in to change notification settings - Fork 0
Conversation
Sometimes it's hard to tell which page a user was on when an error occurred, so adding it in a tag will be useful for debugging. The resolved url is the url that the user requested (like /Parts/iPhone). This is different than `context.req.url`, which can be a link like /_next/data..., which is not the helpful for debugging.
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
QA 🎬 |
packages/sentry/index.tsx
Outdated
}; | ||
|
||
export const setSentryPageContext = ({ url }: PageContextProps) => { | ||
Sentry.setTag('resolved_url', url); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this will be inconsistent and flaky. We're in the context of a JS server that does a bunch of async work. This JS server has only one global context yet it may be serving several requests in parallel. I think we can kill two birds though. I'm gonna try something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this will be inconsistent and flaky. We're in the context of a JS server that does a bunch of async work. This JS server has only one global context yet it may be serving several requests in parallel.
I'm not sure I understand. What exactly are you worried about?
Feel free to push to this branch if you come up with something 👍🏻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wowza I'm seeing a few issues/PR's on sentry-javascript about getting error reporting in getServerSideProps
to work.
getsentry/sentry-javascript#5503
getsentry/sentry-javascript#3880
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow... looks like they already auto-inject code to wrap getServerSideProps()
(given that pull request). But it seems (based on experimentation) that they don't capture the relevant url? I wonder if there's a mechanism (via config) to augment or add to the code that auto-wraps getServerSideProps()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But it seems (based on experimentation) that they don't capture the relevant url?
That's what I had seen, but now that I'm testing this branch, I see the correct url
tag.
I wonder if there's a mechanism (via config) to augment or add to the code that auto-wraps getServerSideProps().
Maybe via the middleware concept that @jarstelfox was talking about? #600 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great thanks for finding all that! Here's an example of a Sentry event from getServerSideProps
that didn't get the url
tag. But many other events from the server are. I can't explain what's causing the discrepancy, I agree with you that it seems like it should work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that it's setting the url, but it isn't setting resolvedUrl. Is there something in this code that makes you think we should be seeing resolvedUrl already?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I did some skimming and cross-referenced the example you linked above.
It looks like sentry hooks into the server and wraps a ton of logic. Most notably Next's Request Handler Factory which is what calls down to setting the url.
I still believe it should be working at the time of the error(even though it clearly is not).
Sentry is passing that data down to itself when a request handler is made. i.e. afterRouted
Maybe someone else can spy what's missing, but I think we should provide our own way of getting the data until we can find a reliable way for sentry to hook the url
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to make sure we're all on the same page, this should only affect page loads where it uses next-link to load json. In those cases, we've seen url set as /_next/...
. resolvedUrl
will be the url of the page that we were really trying to link to. In the code I've read, I see sentry adding the url field, but I haven't seen them add the resolvedUrl field, so I wouldn't expect it to just work without some changes like in this pull.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, Sentry JS SDK maintainer here. Just stumbled onto this thread.
We're currently working on wrapping Next.js data fetching methods (including getServerSideProps
) to improve instrumentation. Currently, the efforts mainly go into properly setting parameterized transaction names (transactions are part of the Sentry performance monitoring product and parameterization means that transactions won't show up as /user/42/post/1337
but rather as /user/[userId]/post/[postId]
, which is generally more useful).
We might explore adding the parameterized route + parameters to errors in some way (or at least provide a way for SDK user's to figure out what parameterized route they're in - maybe we can contribute this to the Next.js repo upstream).
We would love for you to try out the changes as soon as they land!
We want to generate a url from the current context in /frontend and in /packages/sentry. This lets us use it in both places.
Accepts the same param that is passed to `getServerSideProps` so that we can easily call it in each file in /frontend/pages. Clears the Sentry scope before setting the tag, because this is going to be called on a JS server that handles many requests, and we don't want to accidentally include context from another request in a Sentry event. Bumps @sentry/nextjs to 7.8.1, which is what we use in /frontend. Uses the react-library tsconfig.json, because TS was complaining that we imported `urlFromContext()` from a .tsx file.
This approach makes us more confident that we won't accidentally include context from the wrong request in a Sentry event sent from the server (because the server can be handling multiple requests at once).
54f373f
to
7e1519e
Compare
@@ -0,0 +1,6 @@ | |||
import { GetServerSidePropsContext } from 'next'; | |||
|
|||
export function urlFromContext(context: GetServerSidePropsContext): string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI I didn't include this in @ifixit/helpers/nextjs
because doing so would cause a cyclic dependency between @ifixit/sentry
and @ifixit/helpers
.
export function urlFromContext(context: GetServerSidePropsContext): string { | ||
const protocol = context.req.headers.referer?.split('://')[0] || 'https'; | ||
return `${protocol}://${context.req.headers.host}${context.resolvedUrl}`; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could use the actual URL object. I know you may toString it later, but the class may be nice down the road
export function urlFromContext(context: GetServerSidePropsContext): string { | |
const protocol = context.req.headers.referer?.split('://')[0] || 'https'; | |
return `${protocol}://${context.req.headers.host}${context.resolvedUrl}`; | |
} | |
export function urlFromContext(context: GetServerSidePropsContext): URL { | |
const protocol = context.req.headers.referer?.split('://')[0] || 'https'; | |
return new URL(`${protocol}://${context.req.headers.host}${context.resolvedUrl}`); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but we use string urls throughout most of this app unfortunately, so this would be a more siginificant refactor if we were to do it right. I'd rather leave it to another pull.
Nevermind I'm just blind |
We were clearing the scope because we were worried that different requests might pollute each other's scopes on the server. Howevever, it looks like Sentry handles this for us, so we don't need to risk blowing away valuable debugging info: getsentry/sentry-javascript#3788
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CR 👍
Man, crazy that sentry/next does the auto-wrapping of the getServerSideProps()
function. Bummer that it doesn't seem to do the thing all the time.
Carry over QA 🎬 |
Weighing in as the other half of the team working on this project. So glad y'all are excited for this! It's still very much a WIP, so expect it to get better over the next few weeks. Also, feel free to follow along on getsentry/sentry-javascript#5505. It's mostly just some notes I wrote up as I was planning the project, but if there are thoughts about it you want to share, that's a great place. |
Sometimes it's hard to tell which page a user was on when an error occurred, so adding it in a tag will be useful for debugging.
The resolved url is the url that the user requested (like /Parts/iPhone). This is different than
context.req.url
, which can be a link like /_next/data..., which is not the helpful for debugging.QA
Throw an error on any page while running local dev. It should get reported to react-commerce-dev in sentry, and have a
resolved_url
tag.