@@ -174,11 +174,34 @@ export class TryCatch implements Integration {
174174 fn : EventListenerObject ,
175175 options ?: boolean | EventListenerOptions ,
176176 ) : ( ) => void {
177- let callback = ( fn as any ) as WrappedFunction ;
177+ /**
178+ * There are 2 possible scenarios here:
179+ *
180+ * 1. Someone passes a callback, which was attached prior to Sentry initialization, or by using unmodified
181+ * method, eg. `document.addEventListener.call(el, name, handler). In this case, we treat this function
182+ * as a pass-through, and call original `removeEventListener` with it.
183+ *
184+ * 2. Someone passes a callback, which was attached after Sentry was initialized, which means that it was using
185+ * our wrapped version of `addEventListener`, which internally calls `wrap` helper.
186+ * This helper "wraps" whole callback inside a try/catch statement, and attached appropriate metadata to it,
187+ * in order for us to make a distinction between wrapped/non-wrapped functions possible.
188+ * If a function has `__sentry__` property, it means that it was wrapped, and it has additional property
189+ * of `__sentry__original__`, holding the handler. And this original handler, has a reversed link,
190+ * with `__sentry_wrapped__` property, which holds the wrapped version.
191+ *
192+ * When someone adds a handler prior to initialization, and then do it again, but after,
193+ * then we have to detach both of them. Otherwise, if we'd detach only wrapped one, it'd be impossible
194+ * to get rid of the initial handler and it'd stick there forever.
195+ * In case of second scenario, `__sentry_original__` refers to initial handler, and passed function
196+ * is a wrapped version.
197+ */
198+ const callback = ( fn as any ) as WrappedFunction ;
178199 try {
179- callback = callback && ( callback . __sentry_wrapped__ || callback ) ;
200+ if ( callback && callback . __sentry__ ) {
201+ original . call ( this , eventName , callback . __sentry_original__ , options ) ;
202+ }
180203 } catch ( e ) {
181- // ignore, accessing __sentry_wrapped__ will throw in some Selenium environments
204+ // ignore, accessing __sentry__ will throw in some Selenium environments
182205 }
183206 return original . call ( this , eventName , callback , options ) ;
184207 } ;
0 commit comments