Skip to content
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

fix: Correctly detach event listeners #2737

Merged
merged 1 commit into from Jul 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 4 additions & 11 deletions packages/browser/src/integrations/trycatch.ts
Expand Up @@ -185,25 +185,18 @@ export class TryCatch implements Integration {
* our wrapped version of `addEventListener`, which internally calls `wrap` helper.
* This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it,
* in order for us to make a distinction between wrapped/non-wrapped functions possible.
* If a function has `__sentry__` property, it means that it was wrapped, and it has additional property
* of `__sentry__original__`, holding the handler. And this original handler, has a reversed link,
* with `__sentry_wrapped__` property, which holds the wrapped version.
* If a function was wrapped, it has additional property of `__sentry_wrapped__`, holding the handler.
*
* When someone adds a handler prior to initialization, and then do it again, but after,
* then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible
* to get rid of the initial handler and it'd stick there forever.
* In case of second scenario, `__sentry_original__` refers to initial handler, and passed function
* is a wrapped version.
*/
const callback = (fn as any) as WrappedFunction;
try {
if (callback && callback.__sentry__) {
original.call(this, eventName, callback.__sentry_original__, options);
}
original.call(this, eventName, ((fn as unknown) as WrappedFunction).__sentry_wrapped__, options);
} catch (e) {
// ignore, accessing __sentry__ will throw in some Selenium environments
// ignore, accessing __sentry_wrapped__ will throw in some Selenium environments
}
return original.call(this, eventName, callback, options);
return original.call(this, eventName, fn, options);
};
});
}
Expand Down
5 changes: 2 additions & 3 deletions packages/utils/src/instrument.ts
Expand Up @@ -400,13 +400,12 @@ function instrumentDOM(): void {
fn: EventListenerOrEventListenerObject,
options?: boolean | EventListenerOptions,
): () => void {
let callback = fn as WrappedFunction;
try {
callback = callback && (callback.__sentry_wrapped__ || callback);
original.call(this, eventName, ((fn as unknown) as WrappedFunction).__sentry_wrapped__, options);
} catch (e) {
// ignore, accessing __sentry_wrapped__ will throw in some Selenium environments
}
return original.call(this, eventName, callback, options);
return original.call(this, eventName, fn, options);
};
});
});
Expand Down