Skip to content

Commit 3f7d82d

Browse files
committed
WIP - Reworked startup and WIP plugins.
1 parent e4c8607 commit 3f7d82d

21 files changed

+312
-359
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import {
2+
Configuration,
3+
ExceptionlessClient,
4+
parseQueryString
5+
} from "@exceptionless/core";
6+
7+
import { BrowserConfiguration } from "./configuration/BrowserConfiguration.js";
8+
import { BrowserErrorParser } from "./services/BrowserErrorParser.js";
9+
import { BrowserModuleCollector } from "./services/BrowserModuleCollector.js";
10+
import { BrowserRequestInfoCollector } from "./services/BrowserRequestInfoCollector.js";
11+
import { BrowserFetchSubmissionClient } from "./submission/BrowserFetchSubmissionClient.js";
12+
13+
export class BrowserExceptionlessClient extends ExceptionlessClient {
14+
constructor() {
15+
super(new BrowserConfiguration());
16+
}
17+
18+
public async startup(configurationOrApiKey?: (config: Configuration) => void | string): Promise<void> {
19+
if (configurationOrApiKey) {
20+
const settings = this.getDefaultsSettingsFromScriptTag();
21+
if (settings?.apiKey) {
22+
this.config.apiKey = settings.apiKey;
23+
}
24+
25+
if (settings?.serverUrl) {
26+
this.config.serverUrl = settings.serverUrl;
27+
}
28+
29+
if (settings?.serverUrl) {
30+
this.config.serverUrl = settings.serverUrl;
31+
}
32+
33+
if (settings?.includePrivateInformation) {
34+
this.config.includePrivateInformation = settings.includePrivateInformation === "true";
35+
}
36+
37+
this.config.errorParser = new BrowserErrorParser();
38+
this.config.moduleCollector = new BrowserModuleCollector();
39+
this.config.requestInfoCollector = new BrowserRequestInfoCollector();
40+
this.config.submissionClient = new BrowserFetchSubmissionClient(this.config);
41+
42+
// TODO: Register platform specific plugins.
43+
}
44+
45+
await super.startup(configurationOrApiKey);
46+
}
47+
48+
private getDefaultsSettingsFromScriptTag(): { [key: string]: string } {
49+
if (typeof document === "undefined" || !document || !document.getElementsByTagName) {
50+
return null;
51+
}
52+
53+
const scripts = document.getElementsByTagName("script");
54+
for (let index = 0; index < scripts.length; index++) {
55+
if (scripts[index].src?.includes("/exceptionless")) {
56+
return parseQueryString(scripts[index].src.split("?").pop());
57+
}
58+
}
59+
return null;
60+
}
61+
}
62+
63+
//function processUnhandledException(stackTrace: TraceKit.StackTrace, options?: any): void {
64+
// const builder = ExceptionlessClient.default.createUnhandledException(new Error(stackTrace.message || (options || {}).status || "Script error"), "onerror");
65+
// builder.pluginContextData["@@_TraceKit.StackTrace"] = stackTrace;
66+
// builder.submit();
67+
//}
68+
69+
/*
70+
TODO: We currently are unable to parse string exceptions.
71+
function processJQueryAjaxError(event, xhr, settings, error:string): void {
72+
let client = ExceptionlessClient.default;
73+
if (xhr.status === 404) {
74+
client.submitNotFound(settings.url);
75+
} else if (xhr.status !== 401) {
76+
client.createUnhandledException(error, "JQuery.ajaxError")
77+
.setSource(settings.url)
78+
.setProperty("status", xhr.status)
79+
.setProperty("request", settings.data)
80+
.setProperty("response", xhr.responseText && xhr.responseText.slice && xhr.responseText.slice(0, 1024))
81+
.submit();
82+
}
83+
}
84+
*/
85+
86+
//TraceKit.report.subscribe(processUnhandledException);
87+
//TraceKit.extendToAsynchronousCallbacks();
88+
89+
// window && window.addEventListener && window.addEventListener("beforeunload", function () {
90+
// ExceptionlessClient.default.config.queue.process(true);
91+
// });
92+
93+
// if (typeof $ !== "undefined" && $(document)) {
94+
// $(document).ajaxError(processJQueryAjaxError);
95+
// }
96+
97+
//(Error as any).stackTraceLimit = Infinity;
98+
//declare var $;
99+
100+
// browser plugin startup method wires up all handlers?
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Configuration, SettingsManager } from "@exceptionless/core";
2+
import { BrowserLocalStorage } from "../storage/BrowserLocalStorage.js";
3+
import { BrowserLocalStorageProvider } from "../storage/BrowserLocalStorageProvider.js";
4+
5+
export class BrowserConfiguration extends Configuration {
6+
public useLocalStorage(): void {
7+
if (BrowserLocalStorage.isAvailable()) {
8+
this.storage = new BrowserLocalStorageProvider();
9+
SettingsManager.applySavedServerSettings(this);
10+
super.changed();
11+
}
12+
}
13+
}

packages/browser/src/index.ts

Lines changed: 11 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,11 @@
1-
import {
2-
IConfigurationSettings,
3-
Configuration,
4-
SettingsManager,
5-
parseQueryString
6-
} from "@exceptionless/core";
7-
8-
import { DefaultErrorParser } from "./services/DefaultErrorParser.js";
9-
import { DefaultModuleCollector } from "./services/DefaultModuleCollector.js";
10-
import { DefaultRequestInfoCollector } from "./services/DefaultRequestInfoCollector.js";
11-
import { BrowserStorage } from "./storage/BrowserStorage.js";
12-
import { BrowserStorageProvider } from "./storage/BrowserStorageProvider.js";
13-
import { FetchSubmissionClient } from "./submission/FetchSubmissionClient.js";
14-
15-
function getDefaultsSettingsFromScriptTag(): IConfigurationSettings {
16-
if (!document || !document.getElementsByTagName) {
17-
return null;
18-
}
19-
20-
const scripts = document.getElementsByTagName("script");
21-
for (let index = 0; index < scripts.length; index++) {
22-
if (scripts[index].src?.includes("/exceptionless")) {
23-
return parseQueryString(scripts[index].src.split("?").pop());
24-
}
25-
}
26-
return null;
27-
}
28-
29-
// TODO: Do we want to keep this?
30-
Configuration.prototype.useLocalStorage = function() {
31-
if (BrowserStorage.isAvailable()) {
32-
this.storage = new BrowserStorageProvider();
33-
SettingsManager.applySavedServerSettings(this);
34-
this.changed();
35-
}
36-
};
37-
38-
const defaults = Configuration.defaults;
39-
const settings = getDefaultsSettingsFromScriptTag();
40-
if (settings) {
41-
if (settings.apiKey) {
42-
defaults.apiKey = settings.apiKey;
43-
}
44-
45-
if (settings.serverUrl) {
46-
defaults.serverUrl = settings.serverUrl;
47-
}
48-
49-
if (typeof settings.includePrivateInformation === "string") {
50-
defaults.includePrivateInformation = settings.includePrivateInformation === "false" ? false : true;
51-
}
52-
}
53-
54-
defaults.errorParser = new DefaultErrorParser();
55-
defaults.moduleCollector = new DefaultModuleCollector();
56-
defaults.requestInfoCollector = new DefaultRequestInfoCollector();
57-
defaults.submissionClient = (config: Configuration) => new FetchSubmissionClient(config);
58-
59-
if (typeof document === "undefined") {
60-
//return;
61-
}
62-
63-
//function processUnhandledException(stackTrace: TraceKit.StackTrace, options?: any): void {
64-
// const builder = ExceptionlessClient.default.createUnhandledException(new Error(stackTrace.message || (options || {}).status || "Script error"), "onerror");
65-
// builder.pluginContextData["@@_TraceKit.StackTrace"] = stackTrace;
66-
// builder.submit();
67-
//}
68-
69-
/*
70-
TODO: We currently are unable to parse string exceptions.
71-
function processJQueryAjaxError(event, xhr, settings, error:string): void {
72-
let client = ExceptionlessClient.default;
73-
if (xhr.status === 404) {
74-
client.submitNotFound(settings.url);
75-
} else if (xhr.status !== 401) {
76-
client.createUnhandledException(error, "JQuery.ajaxError")
77-
.setSource(settings.url)
78-
.setProperty("status", xhr.status)
79-
.setProperty("request", settings.data)
80-
.setProperty("response", xhr.responseText && xhr.responseText.slice && xhr.responseText.slice(0, 1024))
81-
.submit();
82-
}
83-
}
84-
*/
85-
86-
//TraceKit.report.subscribe(processUnhandledException);
87-
//TraceKit.extendToAsynchronousCallbacks();
88-
89-
// window && window.addEventListener && window.addEventListener("beforeunload", function () {
90-
// ExceptionlessClient.default.config.queue.process(true);
91-
// });
92-
93-
// if (typeof $ !== "undefined" && $(document)) {
94-
// $(document).ajaxError(processJQueryAjaxError);
95-
// }
96-
97-
//(Error as any).stackTraceLimit = Infinity;
98-
//declare var $;
99-
100-
// browser plugin startup method wires up all handlers?
101-
102-
// TODO: Export all services
103-
export { Exceptionless } from "@exceptionless/core";
1+
export { BrowserConfiguration } from "./configuration/BrowserConfiguration.js";
2+
export { BrowserErrorParser } from "./services/BrowserErrorParser.js";
3+
export { BrowserModuleCollector } from "./services/BrowserModuleCollector.js";
4+
export { BrowserRequestInfoCollector } from "./services/BrowserRequestInfoCollector.js";
5+
export { BrowserLocalStorage } from "./storage/BrowserLocalStorage.js";
6+
export { BrowserLocalStorageProvider as BrowserStorageProvider } from "./storage/BrowserLocalStorageProvider.js";
7+
export { BrowserFetchSubmissionClient } from "./submission/BrowserFetchSubmissionClient.js";
8+
export { BrowserExceptionlessClient } from "./BrowserExceptionlessClient.js";
9+
10+
import { BrowserExceptionlessClient } from "./BrowserExceptionlessClient.js";
11+
export const Exceptionless = new BrowserExceptionlessClient();

packages/browser/src/services/DefaultErrorParser.ts renamed to packages/browser/src/services/BrowserErrorParser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
StackFrame
1212
} from "stacktrace-js";
1313

14-
export class DefaultErrorParser implements IErrorParser {
14+
export class BrowserErrorParser implements IErrorParser {
1515
public async parse(context: EventPluginContext, exception: Error): Promise<ErrorInfo> {
1616
function getParameters(parameters: string | string[]): ParameterInfo[] {
1717
const params: string[] = (typeof parameters === "string" ? [parameters] : parameters) || [];

packages/browser/src/services/DefaultModuleCollector.ts renamed to packages/browser/src/services/BrowserModuleCollector.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
parseVersion,
66
} from "@exceptionless/core";
77

8-
export class DefaultModuleCollector implements IModuleCollector {
8+
export class BrowserModuleCollector implements IModuleCollector {
99
public getModules(): ModuleInfo[] {
1010
if (!document || !document.getElementsByTagName) {
1111
return null;

packages/browser/src/services/DefaultRequestInfoCollector.ts renamed to packages/browser/src/services/BrowserRequestInfoCollector.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
RequestInfo,
77
} from "@exceptionless/core";
88

9-
export class DefaultRequestInfoCollector implements IRequestInfoCollector {
9+
export class BrowserRequestInfoCollector implements IRequestInfoCollector {
1010
public getRequestInfo(context: EventPluginContext): RequestInfo {
1111
if (!document || !navigator || !location) {
1212
return null;

packages/browser/src/storage/BrowserStorage.ts renamed to packages/browser/src/storage/BrowserLocalStorage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { KeyValueStorageBase } from "@exceptionless/core";
22

3-
export class BrowserStorage extends KeyValueStorageBase {
3+
export class BrowserLocalStorage extends KeyValueStorageBase {
44
private prefix: string;
55

66
public static isAvailable(): boolean {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import {
2+
IStorage,
3+
IStorageProvider
4+
} from "@exceptionless/core";
5+
6+
import { BrowserLocalStorage } from "./BrowserLocalStorage.js";
7+
8+
export class BrowserLocalStorageProvider implements IStorageProvider {
9+
public queue: IStorage;
10+
public settings: IStorage;
11+
12+
constructor(prefix?: string, maxQueueItems: number = 250) {
13+
this.queue = new BrowserLocalStorage("q", prefix, maxQueueItems);
14+
this.settings = new BrowserLocalStorage("settings", prefix, 1);
15+
}
16+
}

packages/browser/src/storage/BrowserStorageProvider.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

packages/browser/src/submission/FetchSubmissionClient.ts renamed to packages/browser/src/submission/BrowserFetchSubmissionClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
SubmissionClientBase
55
} from "@exceptionless/core";
66

7-
export class FetchSubmissionClient extends SubmissionClientBase {
7+
export class BrowserFetchSubmissionClient extends SubmissionClientBase {
88
protected async fetch<T>(url: string, options: FetchOptions): Promise<Response<T>> {
99
// TODO: Figure out how to set a 10000 timeout.
1010
const requestOptions: RequestInit = {

0 commit comments

Comments
 (0)