diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/event-target/subject.js b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/event-target/subject.js new file mode 100644 index 000000000000..1f28a4f125e0 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/event-target/subject.js @@ -0,0 +1,11 @@ +const btn = document.createElement('button'); +btn.id = 'btn'; +document.body.appendChild(btn); + +const functionListener = function () { + throw new Error('event_listener_error'); +}; + +btn.addEventListener('click', functionListener); + +btn.click(); diff --git a/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/event-target/test.ts b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/event-target/test.ts new file mode 100644 index 000000000000..7900c774a914 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/public-api/instrumentation/eventListener/event-target/test.ts @@ -0,0 +1,29 @@ +import { expect } from '@playwright/test'; +import type { Event } from '@sentry/types'; + +import { sentryTest } from '../../../../../utils/fixtures'; +import { getFirstSentryEnvelopeRequest } from '../../../../../utils/helpers'; + +sentryTest('should capture target name in mechanism data', async ({ getLocalTestUrl, page }) => { + const url = await getLocalTestUrl({ testDir: __dirname }); + + const eventData = await getFirstSentryEnvelopeRequest(page, url); + + expect(eventData.exception?.values).toHaveLength(1); + expect(eventData.exception?.values?.[0]).toMatchObject({ + type: 'Error', + value: 'event_listener_error', + mechanism: { + type: 'instrument', + handled: false, + data: { + function: 'addEventListener', + handler: 'functionListener', + target: 'EventTarget', + }, + }, + stacktrace: { + frames: expect.any(Array), + }, + }); +}); diff --git a/packages/browser/src/integrations/browserapierrors.ts b/packages/browser/src/integrations/browserapierrors.ts index 2a66a9ad3e5b..fffbcff0b09a 100644 --- a/packages/browser/src/integrations/browserapierrors.ts +++ b/packages/browser/src/integrations/browserapierrors.ts @@ -167,19 +167,15 @@ function _wrapEventTarget(target: string): void { const targetObj = globalObject[target]; const proto = targetObj && targetObj.prototype; - if (!proto || Object.prototype.hasOwnProperty.call(proto, 'addEventListener')) { + // eslint-disable-next-line no-prototype-builtins + if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) { return; } fill(proto, 'addEventListener', function (original: VoidFunction,): ( ...args: Parameters - ) => void { - return function ( - this: unknown, - eventName, - fn, - options, - ): (eventName: string, fn: EventListenerObject, capture?: boolean, secure?: boolean) => void { + ) => ReturnType { + return function (this: unknown, eventName, fn, options): VoidFunction { try { if (isEventListenerObject(fn)) { // ESlint disable explanation: @@ -222,11 +218,11 @@ function _wrapEventTarget(target: string): void { }; }); - fill(proto, 'removeEventListener', function (originalRemoveEventListener: () => void,): ( + fill(proto, 'removeEventListener', function (originalRemoveEventListener: VoidFunction,): ( this: unknown, ...args: Parameters - ) => () => void { - return function (this: unknown, eventName, fn, options): () => void { + ) => ReturnType { + return function (this: unknown, eventName, fn, options): VoidFunction { /** * There are 2 possible scenarios here: *