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
Throw uncaught reference error
Throw jQuery ajax error
Throw promise unhandled rejection
+ Throw brower extension error
Log Submission
Submit log event
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/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)
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);
+ });
+});
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