diff --git a/example/browser/index.html b/example/browser/index.html index 6eba68fe..6116a752 100644 --- a/example/browser/index.html +++ b/example/browser/index.html @@ -13,7 +13,8 @@

Error Submission

- + +

Log Submission

diff --git a/example/browser/index.js b/example/browser/index.js index 40bfbcc1..59168aa9 100644 --- a/example/browser/index.js +++ b/example/browser/index.js @@ -95,6 +95,29 @@ document.addEventListener("DOMContentLoaded", () => { }); }); + document + .querySelector("#throw-promise-unhandled-rejection") + .addEventListener("click", () => { + const promiseFn = () => new Promise(function (_, reject) { + switch (Math.floor(Math.random() * 4)) { + case 0: + reject(0); + break; + case 1: + reject(new Error("Promise rejected error")); + break; + case 2: + reject("Promise rejected string"); + break; + case 3: + reject(); + break; + } + }); + + promiseFn(); + }); + document .querySelector("#config-settings-log") .addEventListener("click", () => { diff --git a/packages/browser/src/plugins/BrowserGlobalHandlerPlugin.ts b/packages/browser/src/plugins/BrowserGlobalHandlerPlugin.ts index 73f86d6a..eb06a499 100644 --- a/packages/browser/src/plugins/BrowserGlobalHandlerPlugin.ts +++ b/packages/browser/src/plugins/BrowserGlobalHandlerPlugin.ts @@ -1,7 +1,8 @@ import { ExceptionlessClient, IEventPlugin, - PluginContext + PluginContext, + toError } from "@exceptionless/core"; declare let $: (document: Document) => { ajaxError: { (document: (event: Event, xhr: { responseText: string; status: number; }, settings: { data: unknown; url: string; }, error: string) => void): void; }; }; @@ -25,15 +26,16 @@ export class BrowserGlobalHandlerPlugin implements IEventPlugin { }); window.addEventListener("unhandledrejection", event => { - let error = event.reason; + let reason: unknown = event.reason; try { - const reason = (<{ detail?: { reason: string} }>event).detail?.reason; - if (reason) { - error = reason; + const detailReason = (<{ detail?: { reason: string } }>event).detail?.reason; + if (detailReason) { + reason = detailReason; } } catch (ex) { /* empty */ } - void this._client?.submitUnhandledException(error as Error, "onunhandledrejection"); + const error: Error = toError(reason, "Unhandled rejection") + void this._client?.submitUnhandledException(error, "onunhandledrejection"); }); diff --git a/packages/core/src/Utils.ts b/packages/core/src/Utils.ts index a260068f..55ad91b4 100644 --- a/packages/core/src/Utils.ts +++ b/packages/core/src/Utils.ts @@ -292,3 +292,19 @@ export function toBoolean(input: unknown, defaultValue: boolean = false): boolea return defaultValue; } + +export function toError(errorOrMessage: unknown, defaultMessage = "Unknown Error"): Error { + if (errorOrMessage === null || errorOrMessage === undefined) { + return new Error(defaultMessage); + } + + if (errorOrMessage instanceof Error) { + return errorOrMessage; + } + + if (typeof errorOrMessage === "string") { + return new Error(errorOrMessage); + } + + return new Error(JSON.stringify(errorOrMessage) || defaultMessage); +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 337921da..2e88cf61 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -65,4 +65,5 @@ export { startsWith, stringify, toBoolean, + toError, } from "./Utils.js"; diff --git a/packages/node/src/plugins/NodeGlobalHandlerPlugin.ts b/packages/node/src/plugins/NodeGlobalHandlerPlugin.ts index 73a41bf4..67bbfa3a 100644 --- a/packages/node/src/plugins/NodeGlobalHandlerPlugin.ts +++ b/packages/node/src/plugins/NodeGlobalHandlerPlugin.ts @@ -1,7 +1,8 @@ import { ExceptionlessClient, IEventPlugin, - PluginContext + PluginContext, + toError } from "@exceptionless/core"; export class NodeGlobalHandlerPlugin implements IEventPlugin { @@ -23,7 +24,8 @@ export class NodeGlobalHandlerPlugin implements IEventPlugin { }); process.addListener("unhandledRejection", (reason: unknown | null | undefined) => { - void this._client?.submitUnhandledException(reason, "unhandledRejection"); + const error: Error = toError(reason, "Unhandled rejection") + void this._client?.submitUnhandledException(error, "unhandledRejection"); }); return Promise.resolve();