From ee8143b7c6ce4c7127f067be0451868cd620aae2 Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Wed, 22 Feb 2023 21:06:05 -0600 Subject: [PATCH 1/2] Fixes #70: Ignore errors created from browser extensions --- example/browser/index.html | 1 + example/browser/index.js | 9 ++++ .../browser/src/BrowserExceptionlessClient.ts | 2 + packages/browser/src/index.ts | 1 + .../BrowserIgnoreExtensionErrorsPlugin.ts | 20 ++++++++ ...BrowserIgnoreExtensionErrorsPlugin.test.ts | 50 +++++++++++++++++++ 6 files changed, 83 insertions(+) create mode 100644 packages/browser/src/plugins/BrowserIgnoreExtensionErrorsPlugin.ts create mode 100644 packages/browser/test/plugins/BrowserIgnoreExtensionErrorsPlugin.test.ts diff --git a/example/browser/index.html b/example/browser/index.html index 83c80388..d69681d5 100644 --- a/example/browser/index.html +++ b/example/browser/index.html @@ -15,6 +15,7 @@

Error Submission

+

Log Submission

diff --git a/example/browser/index.js b/example/browser/index.js index b772df3b..73a66904 100644 --- a/example/browser/index.js +++ b/example/browser/index.js @@ -53,6 +53,15 @@ document.addEventListener("DOMContentLoaded", () => { await builder.submit(); }); + document + .querySelector("#throw-browser-extension-error") + .addEventListener("click", () => { + const error = new Error("A Browser Extension Error"); + error.stack = "at () in chrome-extension://bmagokdooijbeehmkpknfglimnifench/firebug-lite.js:line 9716:col 29" + + throw error; + }); + document .querySelector("#throw-custom-error") .addEventListener("click", () => { diff --git a/packages/browser/src/BrowserExceptionlessClient.ts b/packages/browser/src/BrowserExceptionlessClient.ts index e9199b74..d959882f 100644 --- a/packages/browser/src/BrowserExceptionlessClient.ts +++ b/packages/browser/src/BrowserExceptionlessClient.ts @@ -2,6 +2,7 @@ import { Configuration, ExceptionlessClient, SimpleErrorPlugin } from "@exceptio import { BrowserErrorPlugin } from "./plugins/BrowserErrorPlugin.js"; import { BrowserGlobalHandlerPlugin } from "./plugins/BrowserGlobalHandlerPlugin.js"; +import { BrowserIgnoreExtensionErrorsPlugin } from "./plugins/BrowserIgnoreExtensionErrorsPlugin.js"; import { BrowserLifeCyclePlugin } from "./plugins/BrowserLifeCyclePlugin.js"; import { BrowserModuleInfoPlugin } from "./plugins/BrowserModuleInfoPlugin.js"; import { BrowserRequestInfoPlugin } from "./plugins/BrowserRequestInfoPlugin.js"; @@ -13,6 +14,7 @@ export class BrowserExceptionlessClient extends ExceptionlessClient { config.useLocalStorage(); config.addPlugin(new BrowserGlobalHandlerPlugin()); + config.addPlugin(new BrowserIgnoreExtensionErrorsPlugin()); config.addPlugin(new BrowserLifeCyclePlugin()); config.addPlugin(new BrowserModuleInfoPlugin()); config.addPlugin(new BrowserRequestInfoPlugin()); diff --git a/packages/browser/src/index.ts b/packages/browser/src/index.ts index ae31746a..d9e11b46 100644 --- a/packages/browser/src/index.ts +++ b/packages/browser/src/index.ts @@ -1,5 +1,6 @@ export { BrowserErrorPlugin } from "./plugins/BrowserErrorPlugin.js" export { BrowserGlobalHandlerPlugin } from "./plugins/BrowserGlobalHandlerPlugin.js"; +export { BrowserIgnoreExtensionErrorsPlugin } from "./plugins/BrowserIgnoreExtensionErrorsPlugin.js"; export { BrowserLifeCyclePlugin } from "./plugins/BrowserLifeCyclePlugin.js"; export { BrowserModuleInfoPlugin } from "./plugins/BrowserModuleInfoPlugin.js"; export { BrowserRequestInfoPlugin } from "./plugins/BrowserRequestInfoPlugin.js"; diff --git a/packages/browser/src/plugins/BrowserIgnoreExtensionErrorsPlugin.ts b/packages/browser/src/plugins/BrowserIgnoreExtensionErrorsPlugin.ts new file mode 100644 index 00000000..c11a4c68 --- /dev/null +++ b/packages/browser/src/plugins/BrowserIgnoreExtensionErrorsPlugin.ts @@ -0,0 +1,20 @@ +import { + EventPluginContext, + IEventPlugin +} from "@exceptionless/core"; + +export class BrowserIgnoreExtensionErrorsPlugin implements IEventPlugin { + public priority = 15; + public name = "BrowserIgnoreExtensionErrorsPlugin"; + + public async run(context: EventPluginContext): Promise { + const exception = context.eventContext.getException(); + if (exception?.stack && exception.stack.includes("-extension://")) { + // Handles all extensions like chrome-extension://, moz-extension://, ms-browser-extension://, safari-extension:// + context.log.info("Ignoring event with error stack containing browser extension"); + context.cancelled = true; + } + + return Promise.resolve(); + } +} diff --git a/packages/browser/test/plugins/BrowserIgnoreExtensionErrorsPlugin.test.ts b/packages/browser/test/plugins/BrowserIgnoreExtensionErrorsPlugin.test.ts new file mode 100644 index 00000000..ba366b38 --- /dev/null +++ b/packages/browser/test/plugins/BrowserIgnoreExtensionErrorsPlugin.test.ts @@ -0,0 +1,50 @@ +import { describe, test } from "@jest/globals"; +import { expect } from "expect"; + +import { + EventContext, + EventPluginContext, + ExceptionlessClient +} from "@exceptionless/core"; + +import { BrowserIgnoreExtensionErrorsPlugin } from "../../src/plugins/BrowserIgnoreExtensionErrorsPlugin.js"; + +describe("BrowserIgnoreExtensionErrorsPlugin", () => { + let client: ExceptionlessClient; + let plugin: BrowserIgnoreExtensionErrorsPlugin; + + beforeEach(() => { + client = new ExceptionlessClient(); + plugin = new BrowserIgnoreExtensionErrorsPlugin(); + }); + + const run = async (stackTrace?: string | undefined): Promise => { + const error = new Error("Test"); + if (stackTrace) { + error.stack = stackTrace; + } + + const eventContext = new EventContext(); + eventContext.setException(error); + + const context = new EventPluginContext(client, { type: "error" }, eventContext); + + await plugin.run(context); + return context; + } + + test("should not cancel empty stack trace", async () => { + const context = await run(); + expect(context.cancelled).toBe(false); + }); + + test("should not cancel normal stack trace", async () => { + const context = await run("at t() in https://test/Content/js/Exceptionless/exceptionless.min.js:line 1:col 260"); + expect(context.cancelled).toBe(false); + }); + + test("should cancel browser extension stack trace", async () => { + const context = await run("at Object.initialize() in chrome-extension://bmagokdooijbeehmkpknfglimnifench/firebug-lite.js:line 6289:col 29"); + expect(context.cancelled).toBe(true); + }); +}); From 8612119cef65d6bdeb9fc308bc020274e60a6c8c Mon Sep 17 00:00:00 2001 From: Blake Niemyjski Date: Wed, 22 Feb 2023 21:08:45 -0600 Subject: [PATCH 2/2] Fixed lint error --- packages/browser/src/plugins/BrowserGlobalHandlerPlugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/browser/src/plugins/BrowserGlobalHandlerPlugin.ts b/packages/browser/src/plugins/BrowserGlobalHandlerPlugin.ts index be9d06ab..cbb2d44c 100644 --- a/packages/browser/src/plugins/BrowserGlobalHandlerPlugin.ts +++ b/packages/browser/src/plugins/BrowserGlobalHandlerPlugin.ts @@ -46,7 +46,7 @@ export class BrowserGlobalHandlerPlugin implements IEventPlugin { void this._client?.submitNotFound(settings.url); } else if (xhr.status !== 401) { // TODO: Handle async - void this._client?.createUnhandledException(toError(error) as Error, "JQuery.ajaxError") + void this._client?.createUnhandledException(toError(error), "JQuery.ajaxError") .setSource(settings.url) .setProperty("status", xhr.status) .setProperty("request", settings.data) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy