-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(utils): Refactor addInstrumentationHandler
to dedicated methods
#9542
Conversation
let from: string | undefined = handlerData.from; | ||
let to: string | undefined = handlerData.to; | ||
const parsedLoc = parseUrl(WINDOW.location.href); | ||
let parsedFrom = parseUrl(from); | ||
let parsedFrom = from ? parseUrl(from) : undefined; |
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.
this was actually incorrect because from
can technically be undefined
.
// Don't create an additional session for the initial route or if the location did not change | ||
if (!(from === undefined || from === to)) { | ||
if (from !== undefined && from !== to) { |
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.
this condition is a bit easier to read IMHO
// Ignore clicks if ctrl/alt/meta/shift keys are held down as they alter behavior of clicks (e.g. open in new tab) | ||
if ( | ||
isClick && | ||
replay.clickDetector && | ||
event && | ||
event.target && |
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.
it was technically possible to have no target
here (which was surfaced by a test with changed setup) if you have a syntethic event like new Event('click')
.
export interface SentryWrappedXMLHttpRequest { | ||
__sentry_xhr_v2__?: SentryXhrData; | ||
__sentry_xhr_v3__?: SentryXhrData; |
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.
bumped this because method
& url
are required now.
* Use at your own risk, this might break without changelog notice, only used internally. | ||
* @hidden | ||
*/ | ||
export function addClickKeypressInstrumentationHandler(handler: (data: HandlerDataDom) => void): void { |
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.
this name is pretty explicit, alternatively we could do addDomEventInstrumentationHandler
?
WINDOW.onpopstate = function (this: WindowEventHandlers, ...args: any[]): any { | ||
const to = WINDOW.location.href; | ||
// keep track of the current URL state, as we always receive only the updated state | ||
const from = lastHref; |
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.
due to this, from
can actually be undefined
the first time this is run.
const method = isString(args[0]) ? args[0].toUpperCase() : undefined; | ||
const url = parseUrl(args[1]); | ||
|
||
if (!method || !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.
this should never happen, but in the spirit of being very cautious...
|
||
const xhrInfo = this[SENTRY_XHR_DATA_KEY]; | ||
|
||
if (xhrInfo && isString(header) && isString(value)) { |
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.
Being explicit in checking the types here, as theoretically a user could do xhr.setRequestHeader(1, 1)
(that may/should fail, but shouldn't fail on our end).
} | ||
|
||
const handlerData: HandlerDataXhr = { | ||
args: [sentryXhrData.method, sentryXhrData.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.
we used to just pass args: args as [string, string]
here which is actually "wrong" or not really what is expected (I think), because args in here is the args passed to send, which is the body (that we capture separately above).
size-limit report 📦
|
// but since URL is not available in IE11, we do not check for it, | ||
// but simply assume it is an URL and return `toString()` from it (which returns the full URL) | ||
// If that fails, we just return undefined | ||
return (url as URL).toString(); |
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.
We did not handle this case at all, but it is a valid usage of open()
according to MDN.
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.
These changes seem reasonable to me, I only really looked through the replay changes but they seem pretty straightforward
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.
good refactor, feels way better to work with
|
||
if (shouldIgnoreOnError() || (error && error.__sentry_own_request__)) { |
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.
Note here: __sentry_own_request__
is not actually set anymore anywhere except on the XHR object itself. So I figured we can remove this check here and above for the global errors, as no error can/should ever get this property anymore 🤔
This is mostly an internal utility, but changes a bit. This improves the actual type safety a lot, because currently we've been duplicating the types everywhere, sometimes in slightly differing ways, leading to potential issues.
This is mostly an internal utility, but changes a bit. The previous implementation for adding instrumentation had a few issues:
This PR splits up
addInstrumentationHandler
into e.g.addFetchInstrumentationHandler
etc. methods, which improves the actual type safety a lot, because currently we've been duplicating the types everywhere, sometimes in slightly differing ways, leading to potential issues. We had a bunch of issues with xhr & fetch data in Replay recently, so I figured it would finally be a good time to clean this up so we can ensure that the data we get is consistent & reliable. Hopefully this change will prevent issues like we have/had in replay from popping up in the future.Some additional notes:
addClickKeypressInstrumentationHandler()
. I'm open for other naming ideas, but I foundaddDomInstrumentation
a bit too broad, as this could mean a lot of things - and we are strictly only instrumenting clicks and keypresses here. Another name (if we want to be a bit broader) could be e.g.addDomEventInstrumentation
or something like this?url
can be aURL
instead of a string, which we now convert.args
that 1. is not really used and 2. was actually "buggy", as we always returned the args, but foropen
andsend
the args are very different things (but we pretended it's always the "open" args). Now, this is actually always the method & url, and I also deprecated this for v8.data
field, which I removed (this was not set anywhere)addInstrumentationHandler()
method, for removal in v8.