From 1bf1879c90d3222c49f561ea8d9a1df753b9cc0f Mon Sep 17 00:00:00 2001 From: "Eric J. Smith" Date: Fri, 26 Feb 2021 00:31:39 -0600 Subject: [PATCH 1/2] Change models to classes and re-arrange folder structure --- .vscode/settings.json | 3 +- .../src/services/DefaultErrorParser.ts | 16 +- .../src/services/DefaultModuleCollector.ts | 23 +-- .../services/DefaultRequestInfoCollector.ts | 27 +-- packages/core/src/EventBuilder.ts | 98 +++++++---- packages/core/src/ExceptionlessClient.ts | 148 ++++++++++++----- .../core/src/configuration/Configuration.ts | 154 +++++++++++------- packages/core/src/index.ts | 120 +++++++------- packages/core/src/models/Event.ts | 22 +++ .../core/src/models/IClientConfiguration.ts | 4 - packages/core/src/models/IError.ts | 6 - packages/core/src/models/IEvent.ts | 12 -- packages/core/src/models/IInnerError.ts | 12 -- packages/core/src/models/IStackFrame.ts | 7 - .../EnvironmentInfo.ts} | 2 +- .../ManualStackingInfo.ts} | 2 +- .../{IRequestInfo.ts => data/RequestInfo.ts} | 2 +- .../UserDescription.ts} | 2 +- .../models/{IUserInfo.ts => data/UserInfo.ts} | 2 +- .../core/src/models/data/error/ErrorInfo.ts | 6 + .../src/models/data/error/InnerErrorInfo.ts | 12 ++ .../{IMethod.ts => data/error/MethodInfo.ts} | 7 +- .../{IModule.ts => data/error/ModuleInfo.ts} | 3 +- .../error/ParameterInfo.ts} | 3 +- .../src/models/data/error/StackFrameInfo.ts | 7 + .../core/src/plugins/EventPluginContext.ts | 16 +- .../plugins/default/DuplicateCheckerPlugin.ts | 38 +++-- .../plugins/default/EnvironmentInfoPlugin.ts | 14 +- .../plugins/default/EventExclusionPlugin.ts | 91 +++++++---- .../src/plugins/default/HeartbeatPlugin.ts | 15 +- .../src/plugins/default/ModuleInfoPlugin.ts | 17 +- .../src/plugins/default/RequestInfoPlugin.ts | 16 +- packages/core/src/queue/DefaultEventQueue.ts | 87 ++++++---- packages/core/src/queue/IEventQueue.ts | 14 +- .../src/services/IEnvironmentInfoCollector.ts | 6 +- packages/core/src/services/IErrorParser.ts | 6 +- .../core/src/services/IModuleCollector.ts | 4 +- .../src/services/IRequestInfoCollector.ts | 6 +- .../core/src/submission/ISubmissionClient.ts | 16 +- .../src/submission/SubmissionClientBase.ts | 58 ++++--- .../services/NodeEnvironmentInfoCollector.ts | 38 ++--- packages/node/src/services/NodeErrorParser.ts | 40 +++-- .../node/src/services/NodeModuleCollector.ts | 29 ++-- .../src/services/NodeRequestInfoCollector.ts | 29 ++-- tsconfig.json | 4 +- 45 files changed, 753 insertions(+), 491 deletions(-) create mode 100644 packages/core/src/models/Event.ts delete mode 100644 packages/core/src/models/IClientConfiguration.ts delete mode 100644 packages/core/src/models/IError.ts delete mode 100644 packages/core/src/models/IEvent.ts delete mode 100644 packages/core/src/models/IInnerError.ts delete mode 100644 packages/core/src/models/IStackFrame.ts rename packages/core/src/models/{IEnvironmentInfo.ts => data/EnvironmentInfo.ts} (91%) rename packages/core/src/models/{IManualStackingInfo.ts => data/ManualStackingInfo.ts} (62%) rename packages/core/src/models/{IRequestInfo.ts => data/RequestInfo.ts} (88%) rename packages/core/src/models/{IUserDescription.ts => data/UserDescription.ts} (64%) rename packages/core/src/models/{IUserInfo.ts => data/UserInfo.ts} (65%) create mode 100644 packages/core/src/models/data/error/ErrorInfo.ts create mode 100644 packages/core/src/models/data/error/InnerErrorInfo.ts rename packages/core/src/models/{IMethod.ts => data/error/MethodInfo.ts} (62%) rename packages/core/src/models/{IModule.ts => data/error/ModuleInfo.ts} (83%) rename packages/core/src/models/{IParameter.ts => data/error/ParameterInfo.ts} (77%) create mode 100644 packages/core/src/models/data/error/StackFrameInfo.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index 561a9217..efafc030 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -28,5 +28,6 @@ "eslint.validate": [ "javascript", "typescript" - ] + ], + "deno.enable": false } diff --git a/packages/browser/src/services/DefaultErrorParser.ts b/packages/browser/src/services/DefaultErrorParser.ts index 7e58308c..94292c84 100644 --- a/packages/browser/src/services/DefaultErrorParser.ts +++ b/packages/browser/src/services/DefaultErrorParser.ts @@ -1,9 +1,9 @@ import { EventPluginContext, - IError, + ErrorInfo, IErrorParser, - IParameter, - IStackFrame + ParameterInfo, + StackFrameInfo } from '@exceptionless/core'; import { @@ -12,11 +12,11 @@ import { } from 'stacktrace-js'; export class DefaultErrorParser implements IErrorParser { - public async parse(context: EventPluginContext, exception: Error): Promise { - function getParameters(parameters: string | string[]): IParameter[] { + public async parse(context: EventPluginContext, exception: Error): Promise { + function getParameters(parameters: string | string[]): ParameterInfo[] { const params: string[] = (typeof parameters === 'string' ? [parameters] : parameters) || []; - const items: IParameter[] = []; + const items: ParameterInfo[] = []; for (const param of params) { items.push({ name: param }); } @@ -24,9 +24,9 @@ export class DefaultErrorParser implements IErrorParser { return items; } - function getStackFrames(stackFrames: StackFrame[]): IStackFrame[] { + function getStackFrames(stackFrames: StackFrame[]): StackFrameInfo[] { const ANONYMOUS: string = ''; - const frames: IStackFrame[] = []; + const frames: StackFrameInfo[] = []; for (const frame of stackFrames) { const fileName: string = frame.getFileName(); diff --git a/packages/browser/src/services/DefaultModuleCollector.ts b/packages/browser/src/services/DefaultModuleCollector.ts index 2985c985..fd9356b7 100644 --- a/packages/browser/src/services/DefaultModuleCollector.ts +++ b/packages/browser/src/services/DefaultModuleCollector.ts @@ -1,31 +1,32 @@ import { - IModule, - IModuleCollector, getHashCode, - parseVersion -} from '@exceptionless/core'; + IModuleCollector, + ModuleInfo, + parseVersion, +} from "@exceptionless/core"; export class DefaultModuleCollector implements IModuleCollector { - public getModules(): IModule[] { + public getModules(): ModuleInfo[] { if (!document || !document.getElementsByTagName) { return null; } - const modules: IModule[] = []; - const scripts: HTMLCollectionOf = document.getElementsByTagName('script'); + const modules: ModuleInfo[] = []; + const scripts: HTMLCollectionOf = document + .getElementsByTagName("script"); if (scripts && scripts.length > 0) { for (let index = 0; index < scripts.length; index++) { if (scripts[index].src) { modules.push({ module_id: index, - name: scripts[index].src.split('?')[0], - version: parseVersion(scripts[index].src) + name: scripts[index].src.split("?")[0], + version: parseVersion(scripts[index].src), }); } else if (scripts[index].innerHTML) { modules.push({ module_id: index, - name: 'Script Tag', - version: getHashCode(scripts[index].innerHTML).toString() + name: "Script Tag", + version: getHashCode(scripts[index].innerHTML).toString(), }); } } diff --git a/packages/browser/src/services/DefaultRequestInfoCollector.ts b/packages/browser/src/services/DefaultRequestInfoCollector.ts index a48fdc84..68afa5aa 100644 --- a/packages/browser/src/services/DefaultRequestInfoCollector.ts +++ b/packages/browser/src/services/DefaultRequestInfoCollector.ts @@ -1,25 +1,27 @@ import { EventPluginContext, - IRequestInfo, - IRequestInfoCollector, getCookies, - parseQueryString -} from '@exceptionless/core'; + IRequestInfoCollector, + parseQueryString, + RequestInfo, +} from "@exceptionless/core"; export class DefaultRequestInfoCollector implements IRequestInfoCollector { - public getRequestInfo(context: EventPluginContext): IRequestInfo { + public getRequestInfo(context: EventPluginContext): RequestInfo { if (!document || !navigator || !location) { return null; } const config = context.client.config; const exclusions = config.dataExclusions; - const requestInfo: IRequestInfo = { + const requestInfo: RequestInfo = { user_agent: navigator.userAgent, - is_secure: location.protocol === 'https:', + is_secure: location.protocol === "https:", host: location.hostname, - port: location.port && location.port !== '' ? parseInt(location.port, 10) : 80, - path: location.pathname + port: location.port && location.port !== "" + ? parseInt(location.port, 10) + : 80, + path: location.pathname, // client_ip_address: 'TODO' }; @@ -28,10 +30,13 @@ export class DefaultRequestInfoCollector implements IRequestInfoCollector { } if (config.includeQueryString) { - requestInfo.query_string = parseQueryString(location.search.substring(1), exclusions); + requestInfo.query_string = parseQueryString( + location.search.substring(1), + exclusions, + ); } - if (document.referrer && document.referrer !== '') { + if (document.referrer && document.referrer !== "") { requestInfo.referrer = document.referrer; } diff --git a/packages/core/src/EventBuilder.ts b/packages/core/src/EventBuilder.ts index 4e243ce0..b2cc5b94 100644 --- a/packages/core/src/EventBuilder.ts +++ b/packages/core/src/EventBuilder.ts @@ -1,20 +1,25 @@ -import { ExceptionlessClient } from './ExceptionlessClient.js'; -import { IEvent } from './models/IEvent.js'; -import { IManualStackingInfo } from './models/IManualStackingInfo.js'; -import { IRequestInfo } from "./models/IRequestInfo.js"; -import { IUserInfo } from './models/IUserInfo.js'; -import { ContextData } from './plugins/ContextData.js'; -import { EventPluginContext } from './plugins/EventPluginContext.js'; -import { addRange, stringify, isEmpty } from "./Utils.js"; +import { ExceptionlessClient } from "./ExceptionlessClient.js"; +import { Event } from "./models/Event.js"; +import { ManualStackingInfo } from "./models/data/ManualStackingInfo.js"; +import { RequestInfo } from "./models/data/RequestInfo.js"; +import { UserInfo } from "./models/data/UserInfo.js"; +import { ContextData } from "./plugins/ContextData.js"; +import { EventPluginContext } from "./plugins/EventPluginContext.js"; +import { addRange, isEmpty, stringify } from "./Utils.js"; export class EventBuilder { - public target: IEvent; + public target: Event; public client: ExceptionlessClient; public pluginContextData: ContextData; - private _validIdentifierErrorMessage: string = 'must contain between 8 and 100 alphanumeric or \'-\' characters.'; // optimization for minifier. + private _validIdentifierErrorMessage: string = + "must contain between 8 and 100 alphanumeric or '-' characters."; // optimization for minifier. - constructor(event: IEvent, client: ExceptionlessClient, pluginContextData?: ContextData) { + constructor( + event: Event, + client: ExceptionlessClient, + pluginContextData?: ContextData, + ) { this.target = event; this.client = client; this.pluginContextData = pluginContextData || new ContextData(); @@ -53,14 +58,14 @@ export class EventBuilder { */ public setEventReference(name: string, id: string): EventBuilder { if (!name) { - throw new Error('Invalid name'); + throw new Error("Invalid name"); } if (!id || !this.isValidIdentifier(id)) { throw new Error(`Id ${this._validIdentifierErrorMessage}`); } - this.setProperty('@ref:' + name, id); + this.setProperty("@ref:" + name, id); return this; } @@ -74,27 +79,34 @@ export class EventBuilder { public setGeo(latitude: number, longitude: number): EventBuilder { if (latitude < -90.0 || latitude > 90.0) { - throw new Error('Must be a valid latitude value between -90.0 and 90.0.'); + throw new Error("Must be a valid latitude value between -90.0 and 90.0."); } if (longitude < -180.0 || longitude > 180.0) { - throw new Error('Must be a valid longitude value between -180.0 and 180.0.'); + throw new Error( + "Must be a valid longitude value between -180.0 and 180.0.", + ); } this.target.geo = `${latitude},${longitude}`; return this; } - public setUserIdentity(userInfo: IUserInfo): EventBuilder; + public setUserIdentity(userInfo: UserInfo): EventBuilder; public setUserIdentity(identity: string): EventBuilder; public setUserIdentity(identity: string, name: string): EventBuilder; - public setUserIdentity(userInfoOrIdentity: IUserInfo | string, name?: string): EventBuilder { - const userInfo = typeof userInfoOrIdentity !== 'string' ? userInfoOrIdentity : { identity: userInfoOrIdentity, name }; + public setUserIdentity( + userInfoOrIdentity: UserInfo | string, + name?: string, + ): EventBuilder { + const userInfo = typeof userInfoOrIdentity !== "string" + ? userInfoOrIdentity + : { identity: userInfoOrIdentity, name }; if (!userInfo || (!userInfo.identity && !userInfo.name)) { return this; } - this.setProperty('@user', userInfo); + this.setProperty("@user", userInfo); return this; } @@ -105,9 +117,15 @@ export class EventBuilder { * @param description The user's description of the event. * @returns {EventBuilder} */ - public setUserDescription(emailAddress: string, description: string): EventBuilder { + public setUserDescription( + emailAddress: string, + description: string, + ): EventBuilder { if (emailAddress && description) { - this.setProperty('@user_description', { email_address: emailAddress, description }); + this.setProperty("@user_description", { + email_address: emailAddress, + description, + }); } return this; @@ -120,14 +138,17 @@ export class EventBuilder { * @param title An optional title for the stacking information. * @returns {EventBuilder} */ - public setManualStackingInfo(signatureData: any, title?: string): EventBuilder { + public setManualStackingInfo( + signatureData: any, + title?: string, + ): EventBuilder { if (signatureData) { - const stack: IManualStackingInfo = { signature_data: signatureData }; + const stack: ManualStackingInfo = { signature_data: signatureData }; if (title) { stack.title = title; } - this.setProperty('@stack', stack); + this.setProperty("@stack", stack); } return this; @@ -139,7 +160,10 @@ export class EventBuilder { * @param title An optional title for the stacking information. * @returns {EventBuilder} */ - public setManualStackingKey(manualStackingKey: string, title?: string): EventBuilder { + public setManualStackingKey( + manualStackingKey: string, + title?: string, + ): EventBuilder { if (manualStackingKey) { const data = { ManualStackingKey: manualStackingKey }; this.setManualStackingInfo(data, title); @@ -174,7 +198,12 @@ export class EventBuilder { * @param maxDepth The max depth of the object to include. * @param excludedPropertyNames Any property names that should be excluded. */ - public setProperty(name: string, value: any, maxDepth?: number, excludedPropertyNames?: string[]): EventBuilder { + public setProperty( + name: string, + value: any, + maxDepth?: number, + excludedPropertyNames?: string[], + ): EventBuilder { if (!name || (value === undefined || value == null)) { return this; } @@ -183,7 +212,13 @@ export class EventBuilder { this.target.data = {}; } - const result = JSON.parse(stringify(value, this.client.config.dataExclusions.concat(excludedPropertyNames || []), maxDepth)); + const result = JSON.parse( + stringify( + value, + this.client.config.dataExclusions.concat(excludedPropertyNames || []), + maxDepth, + ), + ); if (!isEmpty(result)) { this.target.data[name] = result; } @@ -193,15 +228,15 @@ export class EventBuilder { public markAsCritical(critical: boolean): EventBuilder { if (critical) { - this.addTags('Critical'); + this.addTags("Critical"); } return this; } - public addRequestInfo(request: IRequestInfo): EventBuilder { + public addRequestInfo(request: RequestInfo): EventBuilder { if (request) { - this.pluginContextData['@request'] = request; + this.pluginContextData["@request"] = request; } return this; @@ -223,7 +258,8 @@ export class EventBuilder { for (let index = 0; index < value.length; index++) { const code = value.charCodeAt(index); const isDigit = (code >= 48) && (code <= 57); - const isLetter = ((code >= 65) && (code <= 90)) || ((code >= 97) && (code <= 122)); + const isLetter = ((code >= 65) && (code <= 90)) || + ((code >= 97) && (code <= 122)); const isMinus = code === 45; if (!(isDigit || isLetter) && !isMinus) { diff --git a/packages/core/src/ExceptionlessClient.ts b/packages/core/src/ExceptionlessClient.ts index 2c86fac5..00519be7 100644 --- a/packages/core/src/ExceptionlessClient.ts +++ b/packages/core/src/ExceptionlessClient.ts @@ -1,12 +1,12 @@ -import { Configuration } from './configuration/Configuration.js'; -import { IConfigurationSettings } from './configuration/IConfigurationSettings.js'; -import { SettingsManager } from './configuration/SettingsManager.js'; -import { EventBuilder } from './EventBuilder.js'; -import { IEvent } from './models/IEvent.js'; -import { IUserDescription } from './models/IUserDescription.js'; -import { ContextData } from './plugins/ContextData.js'; -import { EventPluginContext } from './plugins/EventPluginContext.js'; -import { EventPluginManager } from './plugins/EventPluginManager.js'; +import { Configuration } from "./configuration/Configuration.js"; +import { IConfigurationSettings } from "./configuration/IConfigurationSettings.js"; +import { SettingsManager } from "./configuration/SettingsManager.js"; +import { EventBuilder } from "./EventBuilder.js"; +import { Event } from "./models/Event.js"; +import { UserDescription } from "./models/data/UserDescription.js"; +import { ContextData } from "./plugins/ContextData.js"; +import { EventPluginContext } from "./plugins/EventPluginContext.js"; +import { EventPluginManager } from "./plugins/EventPluginManager.js"; export class ExceptionlessClient { /** @@ -25,27 +25,35 @@ export class ExceptionlessClient { constructor(); constructor(settings: IConfigurationSettings); constructor(apiKey: string, serverUrl?: string); - constructor(settingsOrApiKey?: IConfigurationSettings | string, serverUrl?: string) { - this.config = typeof settingsOrApiKey === 'object' + constructor( + settingsOrApiKey?: IConfigurationSettings | string, + serverUrl?: string, + ) { + this.config = typeof settingsOrApiKey === "object" ? new Configuration(settingsOrApiKey) : new Configuration({ apiKey: settingsOrApiKey, serverUrl }); this.updateSettingsTimer(5000); - this.config.onChanged(() => this.updateSettingsTimer(this._timeoutId > 0 ? 5000 : 0)); + this.config.onChanged(() => + this.updateSettingsTimer(this._timeoutId > 0 ? 5000 : 0) + ); this.config.queue.onEventsPosted(() => this.updateSettingsTimer()); } public createException(exception: Error): EventBuilder { const pluginContextData = new ContextData(); pluginContextData.setException(exception); - return this.createEvent(pluginContextData).setType('error'); + return this.createEvent(pluginContextData).setType("error"); } public submitException(exception: Error): Promise { return this.createException(exception).submit(); } - public createUnhandledException(exception: Error, submissionMethod?: string): EventBuilder { + public createUnhandledException( + exception: Error, + submissionMethod?: string, + ): EventBuilder { const builder = this.createException(exception); builder.pluginContextData.markAsUnhandledError(); builder.pluginContextData.setSubmissionMethod(submissionMethod); @@ -53,12 +61,15 @@ export class ExceptionlessClient { return builder; } - public submitUnhandledException(exception: Error, submissionMethod?: string): Promise { + public submitUnhandledException( + exception: Error, + submissionMethod?: string, + ): Promise { return this.createUnhandledException(exception, submissionMethod).submit(); } public createFeatureUsage(feature: string): EventBuilder { - return this.createEvent().setType('usage').setSource(feature); + return this.createEvent().setType("usage").setSource(feature); } public submitFeatureUsage(feature: string): Promise { @@ -67,12 +78,21 @@ export class ExceptionlessClient { public createLog(message: string): EventBuilder; public createLog(source: string, message: string): EventBuilder; - public createLog(source: string, message: string, level: string): EventBuilder; - public createLog(sourceOrMessage: string, message?: string, level?: string): EventBuilder { - let builder = this.createEvent().setType('log'); + public createLog( + source: string, + message: string, + level: string, + ): EventBuilder; + public createLog( + sourceOrMessage: string, + message?: string, + level?: string, + ): EventBuilder { + let builder = this.createEvent().setType("log"); if (level) { - builder = builder.setSource(sourceOrMessage).setMessage(message).setProperty('@level', level); + builder = builder.setSource(sourceOrMessage).setMessage(message) + .setProperty("@level", level); } else if (message) { builder = builder.setSource(sourceOrMessage).setMessage(message); } else { @@ -81,24 +101,37 @@ export class ExceptionlessClient { try { // TODO: Look into using https://www.stevefenton.co.uk/Content/Blog/Date/201304/Blog/Obtaining-A-Class-Name-At-Runtime-In-TypeScript/ const caller: any = this.createLog.caller; - builder = builder.setSource(caller && caller.caller && caller.caller.name); + builder = builder.setSource( + caller && caller.caller && caller.caller.name, + ); } catch (e) { - this.config.log.trace('Unable to resolve log source: ' + e.message); + this.config.log.trace("Unable to resolve log source: " + e.message); } } return builder; } - public submitLog(message: string): Promise - public submitLog(source: string, message: string): Promise - public submitLog(source: string, message: string, level: string): Promise; - public submitLog(sourceOrMessage: string, message?: string, level?: string): Promise { + public submitLog(message: string): Promise; + public submitLog( + source: string, + message: string, + ): Promise; + public submitLog( + source: string, + message: string, + level: string, + ): Promise; + public submitLog( + sourceOrMessage: string, + message?: string, + level?: string, + ): Promise { return this.createLog(sourceOrMessage, message, level).submit(); } public createNotFound(resource: string): EventBuilder { - return this.createEvent().setType('404').setSource(resource); + return this.createEvent().setType("404").setSource(resource); } public submitNotFound(resource: string): Promise { @@ -106,7 +139,7 @@ export class ExceptionlessClient { } public createSessionStart(): EventBuilder { - return this.createEvent().setType('session'); + return this.createEvent().setType("session"); } public submitSessionStart(): Promise { @@ -116,14 +149,24 @@ export class ExceptionlessClient { public async submitSessionEnd(sessionIdOrUserId: string): Promise { if (sessionIdOrUserId && this.config.enabled && this.config.isValid) { this.config.log.info(`Submitting session end: ${sessionIdOrUserId}`); - await this.config.submissionClient.submitHeartbeat(sessionIdOrUserId, true); + await this.config.submissionClient.submitHeartbeat( + sessionIdOrUserId, + true, + ); } } - public async submitSessionHeartbeat(sessionIdOrUserId: string): Promise { + public async submitSessionHeartbeat( + sessionIdOrUserId: string, + ): Promise { if (sessionIdOrUserId && this.config.enabled && this.config.isValid) { - this.config.log.info(`Submitting session heartbeat: ${sessionIdOrUserId}`); - await this.config.submissionClient.submitHeartbeat(sessionIdOrUserId, false); + this.config.log.info( + `Submitting session heartbeat: ${sessionIdOrUserId}`, + ); + await this.config.submissionClient.submitHeartbeat( + sessionIdOrUserId, + false, + ); } } @@ -138,7 +181,10 @@ export class ExceptionlessClient { * @param pluginContextData Any contextual data objects to be used by Exceptionless plugins to gather default information for inclusion in the report information. * @param callback */ - public async submitEvent(event: IEvent, pluginContextData?: ContextData): Promise { + public async submitEvent( + event: Event, + pluginContextData?: ContextData, + ): Promise { const context = new EventPluginContext(this, event, pluginContextData); if (!event) { context.cancelled = true; @@ -146,7 +192,7 @@ export class ExceptionlessClient { } if (!this.config.enabled || !this.config.isValid) { - this.config.log.info('Event submission is currently disabled.'); + this.config.log.info("Event submission is currently disabled."); context.cancelled = true; return context; } @@ -169,7 +215,7 @@ export class ExceptionlessClient { // ensure all required data if (!ev.type || ev.type.length === 0) { - ev.type = 'log'; + ev.type = "log"; } if (!ev.date) { @@ -191,15 +237,30 @@ export class ExceptionlessClient { * @param description The user's description of the event. * @param callback The submission response. */ - public async updateUserEmailAndDescription(referenceId: string, email: string, description: string): Promise { - if (!referenceId || !email || !description || !this.config.enabled || !this.config.isValid) { + public async updateUserEmailAndDescription( + referenceId: string, + email: string, + description: string, + ): Promise { + if ( + !referenceId || !email || !description || !this.config.enabled || + !this.config.isValid + ) { return; } - const userDescription: IUserDescription = { email_address: email, description }; - const response = await this.config.submissionClient.submitUserDescription(referenceId, userDescription); + const userDescription: UserDescription = { + email_address: email, + description, + }; + const response = await this.config.submissionClient.submitUserDescription( + referenceId, + userDescription, + ); if (!response.success) { - this.config.log.error(`Failed to submit user email and description for event '${referenceId}': ${response.status} ${response.message}`); + this.config.log.error( + `Failed to submit user email and description for event '${referenceId}': ${response.status} ${response.message}`, + ); } } @@ -218,8 +279,11 @@ export class ExceptionlessClient { const interval = this.config.updateSettingsWhenIdleInterval; if (interval > 0) { - this.config.log.info(`Update settings every ${interval}ms (${initialDelay || 0}ms delay)`); - const updateSettings = () => void SettingsManager.updateSettings(this.config); + this.config.log.info( + `Update settings every ${interval}ms (${initialDelay || 0}ms delay)`, + ); + const updateSettings = () => + void SettingsManager.updateSettings(this.config); if (initialDelay > 0) { this._timeoutId = setTimeout(updateSettings, initialDelay); } diff --git a/packages/core/src/configuration/Configuration.ts b/packages/core/src/configuration/Configuration.ts index d0e4145d..da8e499d 100644 --- a/packages/core/src/configuration/Configuration.ts +++ b/packages/core/src/configuration/Configuration.ts @@ -1,26 +1,26 @@ -import { DefaultLastReferenceIdManager } from '../lastReferenceIdManager/DefaultLastReferenceIdManager.js'; -import { ILastReferenceIdManager } from '../lastReferenceIdManager/ILastReferenceIdManager.js'; -import { ILog } from '../logging/ILog.js'; -import { ConsoleLog } from '../logging/ConsoleLog.js'; -import { NullLog } from '../logging/NullLog.js'; -import { IUserInfo } from '../models/IUserInfo.js'; -import { HeartbeatPlugin } from '../plugins/default/HeartbeatPlugin.js'; -import { ReferenceIdPlugin } from '../plugins/default/ReferenceIdPlugin.js'; -import { EventPluginContext } from '../plugins/EventPluginContext.js'; -import { EventPluginManager } from '../plugins/EventPluginManager.js'; -import { IEventPlugin } from '../plugins/IEventPlugin.js'; -import { DefaultEventQueue } from '../queue/DefaultEventQueue.js'; -import { IEventQueue } from '../queue/IEventQueue.js'; -import { IEnvironmentInfoCollector } from '../services/IEnvironmentInfoCollector.js'; -import { IErrorParser } from '../services/IErrorParser.js'; -import { IModuleCollector } from '../services/IModuleCollector.js'; -import { IRequestInfoCollector } from '../services/IRequestInfoCollector.js'; -import { InMemoryStorageProvider } from '../storage/InMemoryStorageProvider.js'; -import { IStorageProvider } from '../storage/IStorageProvider.js'; +import { DefaultLastReferenceIdManager } from "../lastReferenceIdManager/DefaultLastReferenceIdManager.js"; +import { ILastReferenceIdManager } from "../lastReferenceIdManager/ILastReferenceIdManager.js"; +import { ILog } from "../logging/ILog.js"; +import { ConsoleLog } from "../logging/ConsoleLog.js"; +import { NullLog } from "../logging/NullLog.js"; +import { UserInfo } from "../models/data/UserInfo.js"; +import { HeartbeatPlugin } from "../plugins/default/HeartbeatPlugin.js"; +import { ReferenceIdPlugin } from "../plugins/default/ReferenceIdPlugin.js"; +import { EventPluginContext } from "../plugins/EventPluginContext.js"; +import { EventPluginManager } from "../plugins/EventPluginManager.js"; +import { IEventPlugin } from "../plugins/IEventPlugin.js"; +import { DefaultEventQueue } from "../queue/DefaultEventQueue.js"; +import { IEventQueue } from "../queue/IEventQueue.js"; +import { IEnvironmentInfoCollector } from "../services/IEnvironmentInfoCollector.js"; +import { IErrorParser } from "../services/IErrorParser.js"; +import { IModuleCollector } from "../services/IModuleCollector.js"; +import { IRequestInfoCollector } from "../services/IRequestInfoCollector.js"; +import { InMemoryStorageProvider } from "../storage/InMemoryStorageProvider.js"; +import { IStorageProvider } from "../storage/IStorageProvider.js"; import { ISubmissionClient } from "../submission/ISubmissionClient.js"; -import { IConfigurationSettings } from './IConfigurationSettings.js'; -import { SettingsManager } from './SettingsManager.js'; -import { merge, addRange, guid } from "../Utils.js"; +import { IConfigurationSettings } from "./IConfigurationSettings.js"; +import { SettingsManager } from "./SettingsManager.js"; +import { addRange, guid, merge } from "../Utils.js"; export class Configuration implements IConfigurationSettings { /** @@ -56,7 +56,8 @@ export class Configuration implements IConfigurationSettings { public environmentInfoCollector: IEnvironmentInfoCollector; public errorParser: IErrorParser; - public lastReferenceIdManager: ILastReferenceIdManager = new DefaultLastReferenceIdManager(); + public lastReferenceIdManager: ILastReferenceIdManager = + new DefaultLastReferenceIdManager(); public log: ILog; public moduleCollector: IModuleCollector; public requestInfoCollector: IRequestInfoCollector; @@ -89,21 +90,21 @@ export class Configuration implements IConfigurationSettings { * @type {string} * @private */ - private _serverUrl: string = 'https://collector.exceptionless.io'; + private _serverUrl: string = "https://collector.exceptionless.io"; /** * The config server url that all configuration will be retrieved from. * @type {string} * @private */ - private _configServerUrl: string = 'https://config.exceptionless.io'; + private _configServerUrl: string = "https://config.exceptionless.io"; /** * The heartbeat server url that all heartbeats will be sent to. * @type {string} * @private */ - private _heartbeatServerUrl: string = 'https://heartbeat.exceptionless.io'; + private _heartbeatServerUrl: string = "https://heartbeat.exceptionless.io"; /** * How often the client should check for updated server settings when idle. The default is every 2 minutes. @@ -150,7 +151,7 @@ export class Configuration implements IConfigurationSettings { constructor(configSettings?: IConfigurationSettings) { function inject(fn: any) { - return typeof fn === 'function' ? fn(this) : fn; + return typeof fn === "function" ? fn(this) : fn; } configSettings = merge(Configuration.defaults, configSettings); @@ -160,17 +161,23 @@ export class Configuration implements IConfigurationSettings { this.serverUrl = configSettings.serverUrl; this.configServerUrl = configSettings.configServerUrl; this.heartbeatServerUrl = configSettings.heartbeatServerUrl; - this.updateSettingsWhenIdleInterval = configSettings.updateSettingsWhenIdleInterval; + this.updateSettingsWhenIdleInterval = + configSettings.updateSettingsWhenIdleInterval; this.includePrivateInformation = configSettings.includePrivateInformation; - this.environmentInfoCollector = inject(configSettings.environmentInfoCollector); + this.environmentInfoCollector = inject( + configSettings.environmentInfoCollector, + ); this.errorParser = inject(configSettings.errorParser); - this.lastReferenceIdManager = inject(configSettings.lastReferenceIdManager) || new DefaultLastReferenceIdManager(); + this.lastReferenceIdManager = + inject(configSettings.lastReferenceIdManager) || + new DefaultLastReferenceIdManager(); this.moduleCollector = inject(configSettings.moduleCollector); this.requestInfoCollector = inject(configSettings.requestInfoCollector); this.submissionBatchSize = inject(configSettings.submissionBatchSize) || 50; this.submissionClient = inject(configSettings.submissionClient); - this.storage = inject(configSettings.storage) || new InMemoryStorageProvider(); + this.storage = inject(configSettings.storage) || + new InMemoryStorageProvider(); this.queue = inject(configSettings.queue) || new DefaultEventQueue(this); SettingsManager.applySavedServerSettings(this); @@ -278,7 +285,7 @@ export class Configuration implements IConfigurationSettings { * @param value */ public set updateSettingsWhenIdleInterval(value: number) { - if (typeof value !== 'number') { + if (typeof value !== "number") { return; } @@ -303,8 +310,10 @@ export class Configuration implements IConfigurationSettings { * @returns {string[]} */ public get dataExclusions(): string[] { - const exclusions: string = this.settings['@@DataExclusions']; - return this._dataExclusions.concat(exclusions && exclusions.split(',') || []); + const exclusions: string = this.settings["@@DataExclusions"]; + return this._dataExclusions.concat( + exclusions && exclusions.split(",") || [], + ); } /** @@ -317,7 +326,10 @@ export class Configuration implements IConfigurationSettings { * @param exclusions */ public addDataExclusions(...exclusions: string[]) { - this._dataExclusions = addRange(this._dataExclusions, ...exclusions); + this._dataExclusions = addRange( + this._dataExclusions, + ...exclusions, + ); } /** @@ -461,8 +473,10 @@ export class Configuration implements IConfigurationSettings { * @returns {string[]} */ public get userAgentBotPatterns(): string[] { - const patterns: string = this.settings['@@UserAgentBotPatterns']; - return this._userAgentBotPatterns.concat(patterns && patterns.split(',') || []); + const patterns: string = this.settings["@@UserAgentBotPatterns"]; + return this._userAgentBotPatterns.concat( + patterns && patterns.split(",") || [], + ); } /** @@ -473,7 +487,10 @@ export class Configuration implements IConfigurationSettings { * @param userAgentBotPatterns */ public addUserAgentBotPatterns(...userAgentBotPatterns: string[]) { - this._userAgentBotPatterns = addRange(this._userAgentBotPatterns, ...userAgentBotPatterns); + this._userAgentBotPatterns = addRange( + this._userAgentBotPatterns, + ...userAgentBotPatterns, + ); } /** @@ -482,7 +499,11 @@ export class Configuration implements IConfigurationSettings { */ public get plugins(): IEventPlugin[] { return this._plugins.sort((p1: IEventPlugin, p2: IEventPlugin) => { - return (p1.priority < p2.priority) ? -1 : (p1.priority > p2.priority) ? 1 : 0; + return (p1.priority < p2.priority) + ? -1 + : (p1.priority > p2.priority) + ? 1 + : 0; }); } @@ -498,11 +519,21 @@ export class Configuration implements IConfigurationSettings { * @param priority Used to determine plugins priority. * @param pluginAction A function that is run. */ - public addPlugin(name: string, priority: number, pluginAction: (context: EventPluginContext) => Promise): void; - public addPlugin(pluginOrName: IEventPlugin | string, priority?: number, pluginAction?: (context: EventPluginContext) => Promise): void { - const plugin: IEventPlugin = pluginAction ? { name: pluginOrName as string, priority, run: pluginAction } : pluginOrName as IEventPlugin; + public addPlugin( + name: string, + priority: number, + pluginAction: (context: EventPluginContext) => Promise, + ): void; + public addPlugin( + pluginOrName: IEventPlugin | string, + priority?: number, + pluginAction?: (context: EventPluginContext) => Promise, + ): void { + const plugin: IEventPlugin = pluginAction + ? { name: pluginOrName as string, priority, run: pluginAction } + : pluginOrName as IEventPlugin; if (!plugin || !plugin.run) { - this.log.error('Add plugin failed: Run method not defined'); + this.log.error("Add plugin failed: Run method not defined"); return; } @@ -539,9 +570,11 @@ export class Configuration implements IConfigurationSettings { * @param name */ public removePlugin(pluginOrName: IEventPlugin | string): void { - const name: string = typeof pluginOrName === 'string' ? pluginOrName : pluginOrName.name; + const name: string = typeof pluginOrName === "string" + ? pluginOrName + : pluginOrName.name; if (!name) { - this.log.error('Remove plugin failed: Plugin name not defined'); + this.log.error("Remove plugin failed: Plugin name not defined"); return; } @@ -560,25 +593,33 @@ export class Configuration implements IConfigurationSettings { */ public setVersion(version: string): void { if (version) { - this.defaultData['@version'] = version; + this.defaultData["@version"] = version; } } - public setUserIdentity(userInfo: IUserInfo): void; + public setUserIdentity(userInfo: UserInfo): void; public setUserIdentity(identity: string): void; public setUserIdentity(identity: string, name: string): void; - public setUserIdentity(userInfoOrIdentity: IUserInfo | string, name?: string): void { - const USER_KEY: string = '@user'; // optimization for minifier. - const userInfo: IUserInfo = typeof userInfoOrIdentity !== 'string' ? userInfoOrIdentity : { identity: userInfoOrIdentity, name }; - - const shouldRemove: boolean = !userInfo || (!userInfo.identity && !userInfo.name); + public setUserIdentity( + userInfoOrIdentity: UserInfo | string, + name?: string, + ): void { + const USER_KEY: string = "@user"; // optimization for minifier. + const userInfo: UserInfo = typeof userInfoOrIdentity !== "string" + ? userInfoOrIdentity + : { identity: userInfoOrIdentity, name }; + + const shouldRemove: boolean = !userInfo || + (!userInfo.identity && !userInfo.name); if (shouldRemove) { delete this.defaultData[USER_KEY]; } else { this.defaultData[USER_KEY] = userInfo; } - this.log.info(`user identity: ${shouldRemove ? 'null' : userInfo.identity}`); + this.log.info( + `user identity: ${shouldRemove ? "null" : userInfo.identity}`, + ); } /** @@ -586,13 +627,16 @@ export class Configuration implements IConfigurationSettings { * @returns {string} */ public get userAgent(): string { - return 'exceptionless-js/1.0.0.0'; + return "exceptionless-js/1.0.0.0"; } /** * Automatically send a heartbeat to keep the session alive. */ - public useSessions(sendHeartbeats: boolean = true, heartbeatInterval: number = 30000): void { + public useSessions( + sendHeartbeats: boolean = true, + heartbeatInterval: number = 30000, + ): void { if (sendHeartbeats) { this.addPlugin(new HeartbeatPlugin(heartbeatInterval)); } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index e9c971c4..4fffde7f 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1,82 +1,82 @@ -export { Configuration } from './configuration/Configuration.js'; -export { IConfigurationSettings } from './configuration/IConfigurationSettings.js'; -export { SettingsManager } from './configuration/SettingsManager.js'; +export { Configuration } from "./configuration/Configuration.js"; +export { IConfigurationSettings } from "./configuration/IConfigurationSettings.js"; +export { SettingsManager } from "./configuration/SettingsManager.js"; -export { DefaultLastReferenceIdManager } from './lastReferenceIdManager/DefaultLastReferenceIdManager.js'; -export { ILastReferenceIdManager } from './lastReferenceIdManager/ILastReferenceIdManager.js'; +export { DefaultLastReferenceIdManager } from "./lastReferenceIdManager/DefaultLastReferenceIdManager.js"; +export { ILastReferenceIdManager } from "./lastReferenceIdManager/ILastReferenceIdManager.js"; -export { ILog } from './logging/ILog.js'; -export { ConsoleLog } from './logging/ConsoleLog.js'; -export { NullLog } from './logging/NullLog.js'; +export { ILog } from "./logging/ILog.js"; +export { ConsoleLog } from "./logging/ConsoleLog.js"; +export { NullLog } from "./logging/NullLog.js"; -export { IClientConfiguration } from './models/IClientConfiguration.js'; -export { IEnvironmentInfo } from './models/IEnvironmentInfo.js'; -export { IError } from './models/IError.js'; -export { IEvent } from './models/IEvent.js'; -export { IInnerError } from './models/IInnerError.js'; -export { IManualStackingInfo } from './models/IManualStackingInfo.js'; -export { IMethod } from './models/IMethod.js'; -export { IModule } from './models/IModule.js'; -export { IParameter } from './models/IParameter.js'; -export { IRequestInfo } from './models/IRequestInfo.js'; -export { IStackFrame } from './models/IStackFrame.js'; -export { IUserDescription } from './models/IUserDescription.js'; -export { IUserInfo } from './models/IUserInfo.js'; +export { Event } from "./models/Event.js"; +export { EnvironmentInfo } from "./models/data/EnvironmentInfo.js"; +export { ManualStackingInfo } from "./models/data/ManualStackingInfo.js"; +export { RequestInfo } from "./models/data/RequestInfo.js"; +export { UserDescription } from "./models/data/UserDescription.js"; +export { UserInfo } from "./models/data/UserInfo.js"; -export { ConfigurationDefaultsPlugin } from './plugins/default/ConfigurationDefaultsPlugin.js'; -export { DuplicateCheckerPlugin } from './plugins/default/DuplicateCheckerPlugin.js'; -export { EnvironmentInfoPlugin } from './plugins/default/EnvironmentInfoPlugin.js'; -export { ErrorPlugin } from './plugins/default/ErrorPlugin.js'; -export { EventExclusionPlugin } from './plugins/default/EventExclusionPlugin.js'; -export { HeartbeatPlugin } from './plugins/default/HeartbeatPlugin.js'; -export { ModuleInfoPlugin } from './plugins/default/ModuleInfoPlugin.js'; -export { ReferenceIdPlugin } from './plugins/default/ReferenceIdPlugin.js'; -export { RequestInfoPlugin } from './plugins/default/RequestInfoPlugin.js'; -export { SubmissionMethodPlugin } from './plugins/default/SubmissionMethodPlugin.js'; -export { ContextData } from './plugins/ContextData.js'; -export { EventPluginContext } from './plugins/EventPluginContext.js'; -export { EventPluginManager } from './plugins/EventPluginManager.js'; -export { IEventPlugin } from './plugins/IEventPlugin.js'; +export { ErrorInfo } from "./models/data/error/ErrorInfo.js"; +export { InnerErrorInfo } from "./models/data/error/InnerErrorInfo.js"; +export { MethodInfo } from "./models/data/error/MethodInfo.js"; +export { ModuleInfo } from "./models/data/error/ModuleInfo.js"; +export { ParameterInfo } from "./models/data/error/ParameterInfo.js"; +export { StackFrameInfo } from "./models/data/error/StackFrameInfo.js"; -export { DefaultEventQueue } from './queue/DefaultEventQueue.js' -export { IEventQueue } from './queue/IEventQueue.js' +export { ConfigurationDefaultsPlugin } from "./plugins/default/ConfigurationDefaultsPlugin.js"; +export { DuplicateCheckerPlugin } from "./plugins/default/DuplicateCheckerPlugin.js"; +export { EnvironmentInfoPlugin } from "./plugins/default/EnvironmentInfoPlugin.js"; +export { ErrorPlugin } from "./plugins/default/ErrorPlugin.js"; +export { EventExclusionPlugin } from "./plugins/default/EventExclusionPlugin.js"; +export { HeartbeatPlugin } from "./plugins/default/HeartbeatPlugin.js"; +export { ModuleInfoPlugin } from "./plugins/default/ModuleInfoPlugin.js"; +export { ReferenceIdPlugin } from "./plugins/default/ReferenceIdPlugin.js"; +export { RequestInfoPlugin } from "./plugins/default/RequestInfoPlugin.js"; +export { SubmissionMethodPlugin } from "./plugins/default/SubmissionMethodPlugin.js"; +export { ContextData } from "./plugins/ContextData.js"; +export { EventPluginContext } from "./plugins/EventPluginContext.js"; +export { EventPluginManager } from "./plugins/EventPluginManager.js"; +export { IEventPlugin } from "./plugins/IEventPlugin.js"; -export { IEnvironmentInfoCollector } from './services/IEnvironmentInfoCollector.js'; -export { IErrorParser } from './services/IErrorParser.js'; -export { IModuleCollector } from './services/IModuleCollector.js'; -export { IRequestInfoCollector } from './services/IRequestInfoCollector.js'; +export { DefaultEventQueue } from "./queue/DefaultEventQueue.js"; +export { IEventQueue } from "./queue/IEventQueue.js"; -export { InMemoryStorage } from './storage/InMemoryStorage.js'; -export { InMemoryStorageProvider } from './storage/InMemoryStorageProvider.js'; -export { IStorage } from './storage/IStorage.js'; -export { IStorageItem } from './storage/IStorageItem.js'; -export { IStorageProvider } from './storage/IStorageProvider.js'; -export { KeyValueStorageBase } from './storage/KeyValueStorageBase.js'; +export { IEnvironmentInfoCollector } from "./services/IEnvironmentInfoCollector.js"; +export { IErrorParser } from "./services/IErrorParser.js"; +export { IModuleCollector } from "./services/IModuleCollector.js"; +export { IRequestInfoCollector } from "./services/IRequestInfoCollector.js"; -export { ISubmissionClient } from './submission/ISubmissionClient.js'; -export { Response } from './submission/Response.js'; +export { InMemoryStorage } from "./storage/InMemoryStorage.js"; +export { InMemoryStorageProvider } from "./storage/InMemoryStorageProvider.js"; +export { IStorage } from "./storage/IStorage.js"; +export { IStorageItem } from "./storage/IStorageItem.js"; +export { IStorageProvider } from "./storage/IStorageProvider.js"; +export { KeyValueStorageBase } from "./storage/KeyValueStorageBase.js"; + +export { ISubmissionClient } from "./submission/ISubmissionClient.js"; +export { Response } from "./submission/Response.js"; export { FetchOptions, - SubmissionClientBase -} from './submission/SubmissionClientBase.js'; + SubmissionClientBase, +} from "./submission/SubmissionClientBase.js"; -export { EventBuilder } from './EventBuilder.js'; -export { ExceptionlessClient } from './ExceptionlessClient.js'; +export { EventBuilder } from "./EventBuilder.js"; +export { ExceptionlessClient } from "./ExceptionlessClient.js"; export { addRange, delay, - getHashCode, + endsWith, getCookies, + getHashCode, guid, + isEmpty, + isMatch, merge, - parseVersion, parseQueryString, + parseVersion, randomNumber, - isMatch, - isEmpty, startsWith, - endsWith, stringify, - toBoolean -} from './Utils.js'; + toBoolean, +} from "./Utils.js"; diff --git a/packages/core/src/models/Event.ts b/packages/core/src/models/Event.ts new file mode 100644 index 00000000..3cf3b07a --- /dev/null +++ b/packages/core/src/models/Event.ts @@ -0,0 +1,22 @@ +export class Event { + /** The event type (ie. error, log message, feature usage). */ + type?: string; + /** The event source (ie. machine name, log name, feature name). */ + source?: string; + /** The date that the event occurred on. */ + date?: Date; + /** A list of tags used to categorize this event. */ + tags?: string[]; + /** The event message. */ + message?: string; + /** The geo coordinates where the event happened. */ + geo?: string; + /** The value of the event if any. */ + value?: number; + /** The number of duplicated events. */ + count?: number; + /** An optional identifier to be used for referencing this event instance at a later time. */ + reference_id?: string; + /** Optional data entries that contain additional information about this event. */ + data?: Record; +} diff --git a/packages/core/src/models/IClientConfiguration.ts b/packages/core/src/models/IClientConfiguration.ts deleted file mode 100644 index bb1c195e..00000000 --- a/packages/core/src/models/IClientConfiguration.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface IClientConfiguration { - settings: Record; - version: number; -} diff --git a/packages/core/src/models/IError.ts b/packages/core/src/models/IError.ts deleted file mode 100644 index bbcd8068..00000000 --- a/packages/core/src/models/IError.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { IInnerError } from './IInnerError.js'; -import { IModule } from './IModule.js'; - -export interface IError extends IInnerError { - modules?: IModule[]; -} diff --git a/packages/core/src/models/IEvent.ts b/packages/core/src/models/IEvent.ts deleted file mode 100644 index 99a6f5b5..00000000 --- a/packages/core/src/models/IEvent.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface IEvent { - type?: string; - source?: string; - date?: Date; - tags?: string[]; - message?: string; - geo?: string; - value?: number; - data?: any; - reference_id?: string; - count?: number; -} diff --git a/packages/core/src/models/IInnerError.ts b/packages/core/src/models/IInnerError.ts deleted file mode 100644 index 27b84fe7..00000000 --- a/packages/core/src/models/IInnerError.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { IMethod } from './IMethod.js'; -import { IStackFrame } from './IStackFrame.js'; - -export interface IInnerError { - message?: string; - type?: string; - code?: string; - data?: any; - inner?: IInnerError; - stack_trace?: IStackFrame[]; - target_method?: IMethod; -} diff --git a/packages/core/src/models/IStackFrame.ts b/packages/core/src/models/IStackFrame.ts deleted file mode 100644 index 6244ee0f..00000000 --- a/packages/core/src/models/IStackFrame.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { IMethod } from './IMethod.js'; - -export interface IStackFrame extends IMethod { - file_name?: string; - line_number?: number; - column?: number; -} diff --git a/packages/core/src/models/IEnvironmentInfo.ts b/packages/core/src/models/data/EnvironmentInfo.ts similarity index 91% rename from packages/core/src/models/IEnvironmentInfo.ts rename to packages/core/src/models/data/EnvironmentInfo.ts index d2b61006..95aeabf9 100644 --- a/packages/core/src/models/IEnvironmentInfo.ts +++ b/packages/core/src/models/data/EnvironmentInfo.ts @@ -1,4 +1,4 @@ -export interface IEnvironmentInfo { +export class EnvironmentInfo { processor_count?: number; total_physical_memory?: number; available_physical_memory?: number; diff --git a/packages/core/src/models/IManualStackingInfo.ts b/packages/core/src/models/data/ManualStackingInfo.ts similarity index 62% rename from packages/core/src/models/IManualStackingInfo.ts rename to packages/core/src/models/data/ManualStackingInfo.ts index 0c64a10f..09668cf0 100644 --- a/packages/core/src/models/IManualStackingInfo.ts +++ b/packages/core/src/models/data/ManualStackingInfo.ts @@ -1,4 +1,4 @@ -export interface IManualStackingInfo { +export class ManualStackingInfo { title?: string; signature_data?: { [key: string]: string }; } diff --git a/packages/core/src/models/IRequestInfo.ts b/packages/core/src/models/data/RequestInfo.ts similarity index 88% rename from packages/core/src/models/IRequestInfo.ts rename to packages/core/src/models/data/RequestInfo.ts index bd740410..5712ef2d 100644 --- a/packages/core/src/models/IRequestInfo.ts +++ b/packages/core/src/models/data/RequestInfo.ts @@ -1,4 +1,4 @@ -export interface IRequestInfo { +export class RequestInfo { user_agent?: string; http_method?: string; is_secure?: boolean; diff --git a/packages/core/src/models/IUserDescription.ts b/packages/core/src/models/data/UserDescription.ts similarity index 64% rename from packages/core/src/models/IUserDescription.ts rename to packages/core/src/models/data/UserDescription.ts index 7f21a7b4..7b53db47 100644 --- a/packages/core/src/models/IUserDescription.ts +++ b/packages/core/src/models/data/UserDescription.ts @@ -1,4 +1,4 @@ -export interface IUserDescription { +export class UserDescription { email_address?: string; description?: string; data?: any; diff --git a/packages/core/src/models/IUserInfo.ts b/packages/core/src/models/data/UserInfo.ts similarity index 65% rename from packages/core/src/models/IUserInfo.ts rename to packages/core/src/models/data/UserInfo.ts index 44c85e9f..931ddf10 100644 --- a/packages/core/src/models/IUserInfo.ts +++ b/packages/core/src/models/data/UserInfo.ts @@ -1,4 +1,4 @@ -export interface IUserInfo { +export class UserInfo { identity?: string; name?: string; data?: any; diff --git a/packages/core/src/models/data/error/ErrorInfo.ts b/packages/core/src/models/data/error/ErrorInfo.ts new file mode 100644 index 00000000..f7cb8342 --- /dev/null +++ b/packages/core/src/models/data/error/ErrorInfo.ts @@ -0,0 +1,6 @@ +import { InnerErrorInfo } from "./InnerErrorInfo.js"; +import { ModuleInfo } from "./ModuleInfo.js"; + +export class ErrorInfo extends InnerErrorInfo { + modules?: ModuleInfo[]; +} diff --git a/packages/core/src/models/data/error/InnerErrorInfo.ts b/packages/core/src/models/data/error/InnerErrorInfo.ts new file mode 100644 index 00000000..c2ef0314 --- /dev/null +++ b/packages/core/src/models/data/error/InnerErrorInfo.ts @@ -0,0 +1,12 @@ +import { MethodInfo } from "./MethodInfo.js"; +import { StackFrameInfo } from "./StackFrameInfo.js"; + +export class InnerErrorInfo { + message?: string; + type?: string; + code?: string; + data?: any; + inner?: InnerErrorInfo; + stack_trace?: StackFrameInfo[]; + target_method?: MethodInfo; +} diff --git a/packages/core/src/models/IMethod.ts b/packages/core/src/models/data/error/MethodInfo.ts similarity index 62% rename from packages/core/src/models/IMethod.ts rename to packages/core/src/models/data/error/MethodInfo.ts index 5c3e087a..81736c69 100644 --- a/packages/core/src/models/IMethod.ts +++ b/packages/core/src/models/data/error/MethodInfo.ts @@ -1,10 +1,9 @@ -import { IParameter } from './IParameter.js'; +import { ParameterInfo } from "./ParameterInfo.js"; -export interface IMethod { +export class MethodInfo { data?: any; generic_arguments?: string[]; - parameters?: IParameter[]; - + parameters?: ParameterInfo[]; is_signature_target?: boolean; declaring_namespace?: string; declaring_type?: string; diff --git a/packages/core/src/models/IModule.ts b/packages/core/src/models/data/error/ModuleInfo.ts similarity index 83% rename from packages/core/src/models/IModule.ts rename to packages/core/src/models/data/error/ModuleInfo.ts index a52ed727..93ed3e4d 100644 --- a/packages/core/src/models/IModule.ts +++ b/packages/core/src/models/data/error/ModuleInfo.ts @@ -1,6 +1,5 @@ -export interface IModule { +export class ModuleInfo { data?: any; - module_id?: number; name?: string; version?: string; diff --git a/packages/core/src/models/IParameter.ts b/packages/core/src/models/data/error/ParameterInfo.ts similarity index 77% rename from packages/core/src/models/IParameter.ts rename to packages/core/src/models/data/error/ParameterInfo.ts index b570e483..2bd00383 100644 --- a/packages/core/src/models/IParameter.ts +++ b/packages/core/src/models/data/error/ParameterInfo.ts @@ -1,7 +1,6 @@ -export interface IParameter { +export class ParameterInfo { data?: any; generic_arguments?: string[]; - name?: string; type?: string; type_namespace?: string; diff --git a/packages/core/src/models/data/error/StackFrameInfo.ts b/packages/core/src/models/data/error/StackFrameInfo.ts new file mode 100644 index 00000000..b34deba6 --- /dev/null +++ b/packages/core/src/models/data/error/StackFrameInfo.ts @@ -0,0 +1,7 @@ +import { MethodInfo } from "./MethodInfo.js"; + +export class StackFrameInfo extends MethodInfo { + file_name?: string; + line_number?: number; + column?: number; +} diff --git a/packages/core/src/plugins/EventPluginContext.ts b/packages/core/src/plugins/EventPluginContext.ts index 3df8b2d8..8468b9c7 100644 --- a/packages/core/src/plugins/EventPluginContext.ts +++ b/packages/core/src/plugins/EventPluginContext.ts @@ -1,15 +1,19 @@ -import { ExceptionlessClient } from '../ExceptionlessClient.js'; -import { ILog } from '../logging/ILog.js'; -import { IEvent } from '../models/IEvent.js'; -import { ContextData } from './ContextData.js'; +import { ExceptionlessClient } from "../ExceptionlessClient.js"; +import { ILog } from "../logging/ILog.js"; +import { Event } from "../models/Event.js"; +import { ContextData } from "./ContextData.js"; export class EventPluginContext { public cancelled: boolean = false; public client: ExceptionlessClient; - public event: IEvent; + public event: Event; public contextData: ContextData; - constructor(client: ExceptionlessClient, event: IEvent, contextData?: ContextData) { + constructor( + client: ExceptionlessClient, + event: Event, + contextData?: ContextData, + ) { this.client = client; this.event = event; this.contextData = contextData ? contextData : new ContextData(); diff --git a/packages/core/src/plugins/default/DuplicateCheckerPlugin.ts b/packages/core/src/plugins/default/DuplicateCheckerPlugin.ts index 89c1e56d..ea4be6c7 100644 --- a/packages/core/src/plugins/default/DuplicateCheckerPlugin.ts +++ b/packages/core/src/plugins/default/DuplicateCheckerPlugin.ts @@ -1,18 +1,21 @@ -import { IInnerError } from '../../models/IInnerError.js'; -import { getHashCode } from '../../Utils.js'; -import { EventPluginContext } from '../EventPluginContext.js'; -import { IEventPlugin } from '../IEventPlugin.js'; +import { InnerErrorInfo } from "../../models/data/error/InnerErrorInfo.js"; +import { getHashCode } from "../../Utils.js"; +import { EventPluginContext } from "../EventPluginContext.js"; +import { IEventPlugin } from "../IEventPlugin.js"; export class DuplicateCheckerPlugin implements IEventPlugin { public priority: number = 1010; - public name: string = 'DuplicateCheckerPlugin'; + public name: string = "DuplicateCheckerPlugin"; private _mergedEvents: MergedEvent[] = []; private _processedHashCodes: TimestampedHash[] = []; private _getCurrentTime: () => number; private _interval: number; - constructor(getCurrentTime: () => number = () => Date.now(), interval: number = 30000) { + constructor( + getCurrentTime: () => number = () => Date.now(), + interval: number = 30000, + ) { this._getCurrentTime = getCurrentTime; this._interval = interval; @@ -24,7 +27,7 @@ export class DuplicateCheckerPlugin implements IEventPlugin { } public run(context: EventPluginContext): Promise { - function calculateHashCode(e: IInnerError): number { + function calculateHashCode(e: InnerErrorInfo): number { let hash = 0; while (e) { if (e.message && e.message.length) { @@ -39,28 +42,37 @@ export class DuplicateCheckerPlugin implements IEventPlugin { return hash; } - const error = context.event.data['@error']; + const error = context.event.data["@error"]; const hashCode = calculateHashCode(error); if (hashCode) { const count = context.event.count || 1; const now = this._getCurrentTime(); - const merged = this._mergedEvents.filter((s) => s.hashCode === hashCode)[0]; + const merged = this._mergedEvents.filter((s) => + s.hashCode === hashCode + )[0]; if (merged) { merged.incrementCount(count); merged.updateDate(context.event.date); - context.log.info('Ignoring duplicate event with hash: ' + hashCode); + context.log.info("Ignoring duplicate event with hash: " + hashCode); context.cancelled = true; } - if (!context.cancelled && this._processedHashCodes.some((h) => h.hash === hashCode && h.timestamp >= (now - this._interval))) { - context.log.trace('Adding event with hash: ' + hashCode); + if ( + !context.cancelled && + this._processedHashCodes.some((h) => + h.hash === hashCode && h.timestamp >= (now - this._interval) + ) + ) { + context.log.trace("Adding event with hash: " + hashCode); this._mergedEvents.push(new MergedEvent(hashCode, context, count)); context.cancelled = true; } if (!context.cancelled) { - context.log.trace('Enqueueing event with hash: ' + hashCode + 'to cache.'); + context.log.trace( + "Enqueueing event with hash: " + hashCode + "to cache.", + ); this._processedHashCodes.push({ hash: hashCode, timestamp: now }); // Only keep the last 50 recent errors. diff --git a/packages/core/src/plugins/default/EnvironmentInfoPlugin.ts b/packages/core/src/plugins/default/EnvironmentInfoPlugin.ts index 3a3876bd..3ef2aa4f 100644 --- a/packages/core/src/plugins/default/EnvironmentInfoPlugin.ts +++ b/packages/core/src/plugins/default/EnvironmentInfoPlugin.ts @@ -1,17 +1,19 @@ -import { IEnvironmentInfo } from '../../models/IEnvironmentInfo.js'; -import { EventPluginContext } from '../EventPluginContext.js'; -import { IEventPlugin } from '../IEventPlugin.js'; +import { EnvironmentInfo } from "../../models/data/EnvironmentInfo.js"; +import { EventPluginContext } from "../EventPluginContext.js"; +import { IEventPlugin } from "../IEventPlugin.js"; export class EnvironmentInfoPlugin implements IEventPlugin { public priority: number = 80; - public name: string = 'EnvironmentInfoPlugin'; + public name: string = "EnvironmentInfoPlugin"; public run(context: EventPluginContext): Promise { - const ENVIRONMENT_KEY: string = '@environment'; // optimization for minifier. + const ENVIRONMENT_KEY: string = "@environment"; // optimization for minifier. const collector = context.client.config.environmentInfoCollector; if (!context.event.data[ENVIRONMENT_KEY] && collector) { - const environmentInfo: IEnvironmentInfo = collector.getEnvironmentInfo(context); + const environmentInfo: EnvironmentInfo = collector.getEnvironmentInfo( + context, + ); if (environmentInfo) { context.event.data[ENVIRONMENT_KEY] = environmentInfo; } diff --git a/packages/core/src/plugins/default/EventExclusionPlugin.ts b/packages/core/src/plugins/default/EventExclusionPlugin.ts index 74e4744a..eb522382 100644 --- a/packages/core/src/plugins/default/EventExclusionPlugin.ts +++ b/packages/core/src/plugins/default/EventExclusionPlugin.ts @@ -1,37 +1,46 @@ -import { IInnerError } from '../../models/IInnerError.js'; -import { toBoolean, startsWith, isMatch } from "../../Utils.js"; -import { EventPluginContext } from '../EventPluginContext.js'; -import { IEventPlugin } from '../IEventPlugin.js'; +import { InnerErrorInfo } from "../../models/data/error/InnerErrorInfo.js"; +import { isMatch, startsWith, toBoolean } from "../../Utils.js"; +import { EventPluginContext } from "../EventPluginContext.js"; +import { IEventPlugin } from "../IEventPlugin.js"; export class EventExclusionPlugin implements IEventPlugin { public priority: number = 45; - public name: string = 'EventExclusionPlugin'; + public name: string = "EventExclusionPlugin"; public run(context: EventPluginContext): Promise { const ev = context.event; const log = context.log; const settings = context.client.config.settings; - if (ev.type === 'log') { + if (ev.type === "log") { const minLogLevel = this.getMinLogLevel(settings, ev.source); - const logLevel = this.getLogLevel(ev.data['@level']); + const logLevel = this.getLogLevel(ev.data["@level"]); if (logLevel !== -1 && (logLevel === 6 || logLevel < minLogLevel)) { - log.info('Cancelling log event due to minimum log level.'); + log.info("Cancelling log event due to minimum log level."); context.cancelled = true; } - } else if (ev.type === 'error') { - let error: IInnerError = ev.data['@error']; + } else if (ev.type === "error") { + let error: InnerErrorInfo = ev.data["@error"]; while (!context.cancelled && error) { - if (this.getTypeAndSourceSetting(settings, ev.type, error.type, true) === false) { - log.info(`Cancelling error from excluded exception type: ${error.type}`); + if ( + this.getTypeAndSourceSetting(settings, ev.type, error.type, true) === + false + ) { + log.info( + `Cancelling error from excluded exception type: ${error.type}`, + ); context.cancelled = true; } error = error.inner; } - } else if (this.getTypeAndSourceSetting(settings, ev.type, ev.source, true) === false) { - log.info(`Cancelling event from excluded type: ${ev.type} and source: ${ev.source}`); + } else if ( + this.getTypeAndSourceSetting(settings, ev.type, ev.source, true) === false + ) { + log.info( + `Cancelling event from excluded type: ${ev.type} and source: ${ev.source}`, + ); context.cancelled = true; } @@ -39,55 +48,67 @@ export class EventExclusionPlugin implements IEventPlugin { } public getLogLevel(level: string): number { - switch ((level || '').toLowerCase().trim()) { - case 'trace': - case 'true': - case '1': - case 'yes': + switch ((level || "").toLowerCase().trim()) { + case "trace": + case "true": + case "1": + case "yes": return 0; - case 'debug': + case "debug": return 1; - case 'info': + case "info": return 2; - case 'warn': + case "warn": return 3; - case 'error': + case "error": return 4; - case 'fatal': + case "fatal": return 5; - case 'off': - case 'false': - case '0': - case 'no': + case "off": + case "false": + case "0": + case "no": return 6; default: return -1; } } - public getMinLogLevel(configSettings: Record, source): number { - return this.getLogLevel(this.getTypeAndSourceSetting(configSettings, 'log', source, 'other') + ''); + public getMinLogLevel( + configSettings: Record, + source, + ): number { + return this.getLogLevel( + this.getTypeAndSourceSetting(configSettings, "log", source, "other") + "", + ); } - private getTypeAndSourceSetting(configSettings: Record = {}, type: string, source: string, defaultValue: string | boolean): string | boolean { + private getTypeAndSourceSetting( + configSettings: Record = {}, + type: string, + source: string, + defaultValue: string | boolean, + ): string | boolean { if (!type) { return defaultValue; } if (!source) { - source = ''; + source = ""; } - const isLog: boolean = type === 'log'; + const isLog: boolean = type === "log"; const sourcePrefix: string = `@@${type}:`; const value: string = configSettings[sourcePrefix + source]; if (value) { - return isLog ? value: toBoolean(value); + return isLog ? value : toBoolean(value); } // sort object keys longest first, then alphabetically. - const sortedKeys = Object.keys(configSettings).sort((a, b) => b.length - a.length || a.localeCompare(b)); + const sortedKeys = Object.keys(configSettings).sort((a, b) => + b.length - a.length || a.localeCompare(b) + ); for (const index in sortedKeys) { const key: string = sortedKeys[index]; if (!startsWith(key.toLowerCase(), sourcePrefix)) { diff --git a/packages/core/src/plugins/default/HeartbeatPlugin.ts b/packages/core/src/plugins/default/HeartbeatPlugin.ts index dfe56e7d..054f8ef0 100644 --- a/packages/core/src/plugins/default/HeartbeatPlugin.ts +++ b/packages/core/src/plugins/default/HeartbeatPlugin.ts @@ -1,10 +1,10 @@ -import { IUserInfo } from '../../models/IUserInfo.js'; -import { EventPluginContext } from '../EventPluginContext.js'; -import { IEventPlugin } from '../IEventPlugin.js'; +import { UserInfo } from "../../models/data/UserInfo.js"; +import { EventPluginContext } from "../EventPluginContext.js"; +import { IEventPlugin } from "../IEventPlugin.js"; export class HeartbeatPlugin implements IEventPlugin { public priority: number = 100; - public name: string = 'HeartbeatPlugin'; + public name: string = "HeartbeatPlugin"; private _interval: number; private _intervalId: any; @@ -16,9 +16,12 @@ export class HeartbeatPlugin implements IEventPlugin { public run(context: EventPluginContext): Promise { clearInterval(this._intervalId); - const user: IUserInfo = context.event.data['@user']; + const user: UserInfo = context.event.data["@user"]; if (user && user.identity) { - this._intervalId = setInterval(() => context.client.submitSessionHeartbeat(user.identity), this._interval); + this._intervalId = setInterval( + () => context.client.submitSessionHeartbeat(user.identity), + this._interval, + ); } return Promise.resolve(); diff --git a/packages/core/src/plugins/default/ModuleInfoPlugin.ts b/packages/core/src/plugins/default/ModuleInfoPlugin.ts index 6cde47a8..4e0721bb 100644 --- a/packages/core/src/plugins/default/ModuleInfoPlugin.ts +++ b/packages/core/src/plugins/default/ModuleInfoPlugin.ts @@ -1,17 +1,20 @@ -import { IModule } from '../../models/IModule.js'; -import { EventPluginContext } from '../EventPluginContext.js'; -import { IEventPlugin } from '../IEventPlugin.js'; +import { ModuleInfo } from "../../models/data/error/ModuleInfo.js"; +import { EventPluginContext } from "../EventPluginContext.js"; +import { IEventPlugin } from "../IEventPlugin.js"; export class ModuleInfoPlugin implements IEventPlugin { public priority: number = 50; - public name: string = 'ModuleInfoPlugin'; + public name: string = "ModuleInfoPlugin"; public run(context: EventPluginContext): Promise { - const ERROR_KEY: string = '@error'; // optimization for minifier. + const ERROR_KEY: string = "@error"; // optimization for minifier. const collector = context.client.config.moduleCollector; - if (context.event.data[ERROR_KEY] && !context.event.data['@error'].modules && collector) { - const modules: IModule[] = collector.getModules(); + if ( + context.event.data[ERROR_KEY] && !context.event.data["@error"].modules && + collector + ) { + const modules: ModuleInfo[] = collector.getModules(); if (modules && modules.length > 0) { context.event.data[ERROR_KEY].modules = modules; } diff --git a/packages/core/src/plugins/default/RequestInfoPlugin.ts b/packages/core/src/plugins/default/RequestInfoPlugin.ts index ec282136..3b7c1136 100644 --- a/packages/core/src/plugins/default/RequestInfoPlugin.ts +++ b/packages/core/src/plugins/default/RequestInfoPlugin.ts @@ -1,22 +1,24 @@ -import { IRequestInfo } from '../../models/IRequestInfo.js'; +import { RequestInfo } from "../../models/data/RequestInfo.js"; import { isMatch } from "../../Utils.js"; -import { EventPluginContext } from '../EventPluginContext.js'; -import { IEventPlugin } from '../IEventPlugin.js'; +import { EventPluginContext } from "../EventPluginContext.js"; +import { IEventPlugin } from "../IEventPlugin.js"; export class RequestInfoPlugin implements IEventPlugin { public priority: number = 70; - public name: string = 'RequestInfoPlugin'; + public name: string = "RequestInfoPlugin"; public run(context: EventPluginContext): Promise { - const REQUEST_KEY: string = '@request'; // optimization for minifier. + const REQUEST_KEY: string = "@request"; // optimization for minifier. const config = context.client.config; const collector = config.requestInfoCollector; if (!context.event.data[REQUEST_KEY] && collector) { - const requestInfo: IRequestInfo = collector.getRequestInfo(context); + const requestInfo: RequestInfo = collector.getRequestInfo(context); if (requestInfo) { if (isMatch(requestInfo.user_agent, config.userAgentBotPatterns)) { - context.log.info('Cancelling event as the request user agent matches a known bot pattern'); + context.log.info( + "Cancelling event as the request user agent matches a known bot pattern", + ); context.cancelled = true; } else { context.event.data[REQUEST_KEY] = requestInfo; diff --git a/packages/core/src/queue/DefaultEventQueue.ts b/packages/core/src/queue/DefaultEventQueue.ts index db6536d4..f9548a06 100644 --- a/packages/core/src/queue/DefaultEventQueue.ts +++ b/packages/core/src/queue/DefaultEventQueue.ts @@ -1,8 +1,8 @@ -import { Configuration } from '../configuration/Configuration.js'; -import { ILog } from '../logging/ILog.js'; -import { IEvent } from '../models/IEvent.js'; -import { IEventQueue } from '../queue/IEventQueue.js'; -import { IStorageItem } from '../storage/IStorageItem.js'; +import { Configuration } from "../configuration/Configuration.js"; +import { ILog } from "../logging/ILog.js"; +import { Event } from "../models/Event.js"; +import { IEventQueue } from "../queue/IEventQueue.js"; +import { IStorageItem } from "../storage/IStorageItem.js"; import { Response } from "../submission/Response.js"; export class DefaultEventQueue implements IEventQueue { @@ -18,7 +18,9 @@ export class DefaultEventQueue implements IEventQueue { * @type {Array} * @private */ - private _handlers: Array<(events: IEvent[], response: Response) => void> = []; + private _handlers: Array< + (events: Event[], response: Response) => void + > = []; /** * Suspends processing until the specified time. @@ -52,8 +54,8 @@ export class DefaultEventQueue implements IEventQueue { this._config = config; } - public enqueue(event: IEvent): void { - const eventWillNotBeQueued: string = 'The event will not be queued.'; // optimization for minifier. + public enqueue(event: Event): void { + const eventWillNotBeQueued: string = "The event will not be queued."; // optimization for minifier. const config: Configuration = this._config; // Optimization for minifier. const log: ILog = config.log; // Optimization for minifier. @@ -68,14 +70,18 @@ export class DefaultEventQueue implements IEventQueue { } if (this.areQueuedItemsDiscarded()) { - log.info(`Queue items are currently being discarded. ${eventWillNotBeQueued}`); + log.info( + `Queue items are currently being discarded. ${eventWillNotBeQueued}`, + ); return; } this.ensureQueueTimer(); const timestamp = config.storage.queue.save(event); - const logText = `type=${event.type} ${event.reference_id ? 'refid=' + event.reference_id : ''}`; + const logText = `type=${event.type} ${ + event.reference_id ? "refid=" + event.reference_id : "" + }`; if (timestamp) { log.info(`Enqueuing event: ${timestamp} ${logText}`); } else { @@ -84,7 +90,7 @@ export class DefaultEventQueue implements IEventQueue { } public async process(): Promise { - const queueNotProcessed: string = 'The queue will not be processed.'; // optimization for minifier. + const queueNotProcessed: string = "The queue will not be processed."; // optimization for minifier. const config: Configuration = this._config; // Optimization for minifier. const log: ILog = config.log; // Optimization for minifier. @@ -92,7 +98,7 @@ export class DefaultEventQueue implements IEventQueue { return; } - log.info('Processing queue...'); + log.info("Processing queue..."); if (!config.enabled) { log.info(`Configuration is disabled: ${queueNotProcessed}`); return; @@ -114,10 +120,12 @@ export class DefaultEventQueue implements IEventQueue { } log.info(`Sending ${events.length} events to ${config.serverUrl}`); - const response = await config.submissionClient.submitEvents(events.map((e) => e.value)); + const response = await config.submissionClient.submitEvents( + events.map((e) => e.value), + ); this.processSubmissionResponse(response, events); this.eventsPosted(events.map((e) => e.value), response); - log.info('Finished processing queue.'); + log.info("Finished processing queue."); this._processingQueue = false; } catch (ex) { log.error(`Error processing queue: ${ex}`); @@ -126,7 +134,11 @@ export class DefaultEventQueue implements IEventQueue { } } - public suspendProcessing(durationInMinutes?: number, discardFutureQueuedItems?: boolean, clearQueue?: boolean): void { + public suspendProcessing( + durationInMinutes?: number, + discardFutureQueuedItems?: boolean, + clearQueue?: boolean, + ): void { const config: Configuration = this._config; // Optimization for minifier. if (!durationInMinutes || durationInMinutes <= 0) { @@ -134,7 +146,9 @@ export class DefaultEventQueue implements IEventQueue { } config.log.info(`Suspending processing for ${durationInMinutes} minutes.`); - this._suspendProcessingUntil = new Date(new Date().getTime() + (durationInMinutes * 60000)); + this._suspendProcessingUntil = new Date( + new Date().getTime() + (durationInMinutes * 60000), + ); if (discardFutureQueuedItems) { this._discardQueuedItemsUntil = this._suspendProcessingUntil; @@ -147,11 +161,13 @@ export class DefaultEventQueue implements IEventQueue { } // TODO: See if this makes sense. - public onEventsPosted(handler: (events: IEvent[], response: Response) => void): void { + public onEventsPosted( + handler: (events: Event[], response: Response) => void, + ): void { handler && this._handlers.push(handler); } - private eventsPosted(events: IEvent[], response: Response) { + private eventsPosted(events: Event[], response: Response) { const handlers = this._handlers; // optimization for minifier. for (const handler of handlers) { try { @@ -163,7 +179,8 @@ export class DefaultEventQueue implements IEventQueue { } private areQueuedItemsDiscarded(): boolean { - return this._discardQueuedItemsUntil && this._discardQueuedItemsUntil > new Date(); + return this._discardQueuedItemsUntil && + this._discardQueuedItemsUntil > new Date(); } private ensureQueueTimer(): void { @@ -173,7 +190,8 @@ export class DefaultEventQueue implements IEventQueue { } private isQueueProcessingSuspended(): boolean { - return this._suspendProcessingUntil && this._suspendProcessingUntil > new Date(); + return this._suspendProcessingUntil && + this._suspendProcessingUntil > new Date(); } private onProcessQueue(): void { @@ -182,8 +200,11 @@ export class DefaultEventQueue implements IEventQueue { } } - private processSubmissionResponse(response: Response, events: IStorageItem[]): void { - const noSubmission: string = 'The event will not be submitted.'; // Optimization for minifier. + private processSubmissionResponse( + response: Response, + events: IStorageItem[], + ): void { + const noSubmission: string = "The event will not be submitted."; // Optimization for minifier. const config: Configuration = this._config; // Optimization for minifier. const log: ILog = config.log; // Optimization for minifier. @@ -195,21 +216,25 @@ export class DefaultEventQueue implements IEventQueue { if (response.status === 429 || response.status === 503) { // You are currently over your rate limit or the servers are under stress. - log.error('Server returned service unavailable.'); + log.error("Server returned service unavailable."); this.suspendProcessing(); return; } if (response.status === 402) { // If the organization over the rate limit then discard the event. - log.info('Too many events have been submitted, please upgrade your plan.'); + log.info( + "Too many events have been submitted, please upgrade your plan.", + ); this.suspendProcessing(null, true, true); return; } if (response.status === 401 || response.status === 403) { // The api key was suspended or could not be authorized. - log.info(`Unable to authenticate, please check your configuration. ${noSubmission}`); + log.info( + `Unable to authenticate, please check your configuration. ${noSubmission}`, + ); this.suspendProcessing(15); this.removeEvents(events); return; @@ -224,10 +249,13 @@ export class DefaultEventQueue implements IEventQueue { } if (response.status === 413) { - const message = 'Event submission discarded for being too large.'; + const message = "Event submission discarded for being too large."; if (config.submissionBatchSize > 1) { log.error(`${message} Retrying with smaller batch size.`); - config.submissionBatchSize = Math.max(1, Math.round(config.submissionBatchSize / 1.5)); + config.submissionBatchSize = Math.max( + 1, + Math.round(config.submissionBatchSize / 1.5), + ); } else { log.error(`${message} ${noSubmission}`); this.removeEvents(events); @@ -236,7 +264,10 @@ export class DefaultEventQueue implements IEventQueue { return; } - log.error(`Error submitting events: ${response.message || 'Please check the network tab for more info.'}`); + log.error( + `Error submitting events: ${response.message || + "Please check the network tab for more info."}`, + ); this.suspendProcessing(); } diff --git a/packages/core/src/queue/IEventQueue.ts b/packages/core/src/queue/IEventQueue.ts index 4722ac6a..daa88edd 100644 --- a/packages/core/src/queue/IEventQueue.ts +++ b/packages/core/src/queue/IEventQueue.ts @@ -1,10 +1,16 @@ -import { IEvent } from '../models/IEvent.js'; +import { Event } from "../models/Event.js"; import { Response } from "../submission/Response.js"; export interface IEventQueue { - enqueue(event: IEvent): void; + enqueue(event: Event): void; process(): void; - suspendProcessing(durationInMinutes?: number, discardFutureQueuedItems?: boolean, clearQueue?: boolean): void; + suspendProcessing( + durationInMinutes?: number, + discardFutureQueuedItems?: boolean, + clearQueue?: boolean, + ): void; // TODO: See if this makes sense. - onEventsPosted(handler: (events: IEvent[], response: Response) => void): void; + onEventsPosted( + handler: (events: Event[], response: Response) => void, + ): void; } diff --git a/packages/core/src/services/IEnvironmentInfoCollector.ts b/packages/core/src/services/IEnvironmentInfoCollector.ts index 1eb7eaf3..ba7f2289 100644 --- a/packages/core/src/services/IEnvironmentInfoCollector.ts +++ b/packages/core/src/services/IEnvironmentInfoCollector.ts @@ -1,6 +1,6 @@ -import { IEnvironmentInfo } from '../models/IEnvironmentInfo.js'; -import { EventPluginContext } from '../plugins/EventPluginContext.js'; +import { EnvironmentInfo } from "../models/data/EnvironmentInfo.js"; +import { EventPluginContext } from "../plugins/EventPluginContext.js"; export interface IEnvironmentInfoCollector { - getEnvironmentInfo(context: EventPluginContext): IEnvironmentInfo; + getEnvironmentInfo(context: EventPluginContext): EnvironmentInfo; } diff --git a/packages/core/src/services/IErrorParser.ts b/packages/core/src/services/IErrorParser.ts index 55cce10b..9bcc46f1 100644 --- a/packages/core/src/services/IErrorParser.ts +++ b/packages/core/src/services/IErrorParser.ts @@ -1,6 +1,6 @@ -import { IError } from '../models/IError.js'; -import { EventPluginContext } from '../plugins/EventPluginContext.js'; +import { ErrorInfo } from "../models/data/error/ErrorInfo.js"; +import { EventPluginContext } from "../plugins/EventPluginContext.js"; export interface IErrorParser { - parse(context: EventPluginContext, exception: Error): Promise; + parse(context: EventPluginContext, exception: ErrorInfo): Promise; } diff --git a/packages/core/src/services/IModuleCollector.ts b/packages/core/src/services/IModuleCollector.ts index 11c3b319..63abbdf5 100644 --- a/packages/core/src/services/IModuleCollector.ts +++ b/packages/core/src/services/IModuleCollector.ts @@ -1,5 +1,5 @@ -import { IModule } from '../models/IModule.js'; +import { ModuleInfo } from "../models/data/error/ModuleInfo.js"; export interface IModuleCollector { - getModules(): IModule[]; + getModules(): ModuleInfo[]; } diff --git a/packages/core/src/services/IRequestInfoCollector.ts b/packages/core/src/services/IRequestInfoCollector.ts index 4714dd12..a42d4fc7 100644 --- a/packages/core/src/services/IRequestInfoCollector.ts +++ b/packages/core/src/services/IRequestInfoCollector.ts @@ -1,6 +1,6 @@ -import { IRequestInfo } from '../models/IRequestInfo.js'; -import { EventPluginContext } from '../plugins/EventPluginContext.js'; +import { RequestInfo } from "../models/data/RequestInfo.js"; +import { EventPluginContext } from "../plugins/EventPluginContext.js"; export interface IRequestInfoCollector { - getRequestInfo(context: EventPluginContext): IRequestInfo; + getRequestInfo(context: EventPluginContext): RequestInfo; } diff --git a/packages/core/src/submission/ISubmissionClient.ts b/packages/core/src/submission/ISubmissionClient.ts index 0fe74330..db1a6491 100644 --- a/packages/core/src/submission/ISubmissionClient.ts +++ b/packages/core/src/submission/ISubmissionClient.ts @@ -1,11 +1,17 @@ import { ClientSettings } from "../configuration/SettingsManager.js"; -import { IEvent } from '../models/IEvent.js'; -import { IUserDescription } from '../models/IUserDescription.js'; +import { Event } from "../models/Event.js"; +import { UserDescription } from "../models/data/UserDescription.js"; import { Response } from "./Response"; export interface ISubmissionClient { getSettings(version: number): Promise>; - submitEvents(events: IEvent[]): Promise>; - submitUserDescription(referenceId: string, description: IUserDescription): Promise>; - submitHeartbeat(sessionIdOrUserId: string, closeSession: boolean): Promise>; + submitEvents(events: Event[]): Promise>; + submitUserDescription( + referenceId: string, + description: UserDescription, + ): Promise>; + submitHeartbeat( + sessionIdOrUserId: string, + closeSession: boolean, + ): Promise>; } diff --git a/packages/core/src/submission/SubmissionClientBase.ts b/packages/core/src/submission/SubmissionClientBase.ts index 34dfe95e..bf5eb9ac 100644 --- a/packages/core/src/submission/SubmissionClientBase.ts +++ b/packages/core/src/submission/SubmissionClientBase.ts @@ -1,17 +1,21 @@ -import { Configuration } from '../configuration/Configuration.js'; -import { ClientSettings, SettingsManager } from "../configuration/SettingsManager.js"; -import { IEvent } from '../models/IEvent.js'; -import { IUserDescription } from '../models/IUserDescription.js'; +import { Configuration } from "../configuration/Configuration.js"; +import { + ClientSettings, + SettingsManager, +} from "../configuration/SettingsManager.js"; +import { Event } from "../models/Event.js"; +import { UserDescription } from "../models/data/UserDescription.js"; import { ISubmissionClient } from "./ISubmissionClient"; import { Response } from "./Response"; export interface FetchOptions { - method: 'GET' | 'POST' - body?: string + method: "GET" | "POST"; + body?: string; } export abstract class SubmissionClientBase implements ISubmissionClient { - protected readonly ConfigurationVersionHeader: string = 'x-exceptionless-configversion'; + protected readonly ConfigurationVersionHeader: string = + "x-exceptionless-configversion"; public constructor(protected config: Configuration) { } @@ -19,14 +23,14 @@ export abstract class SubmissionClientBase implements ISubmissionClient { public getSettings(version: number): Promise> { const url = `${this.config.serverUrl}/api/v2/projects/config?v=${version}`; return this.fetch(url, { - method: 'GET' + method: "GET", }); } - public async submitEvents(events: IEvent[]): Promise> { + public async submitEvents(events: Event[]): Promise> { const url = `${this.config.serverUrl}/api/v2/events`; const response = await this.fetch(url, { - method: 'POST', + method: "POST", body: JSON.stringify(events) }); @@ -34,36 +38,50 @@ export abstract class SubmissionClientBase implements ISubmissionClient { return response; } - public async submitUserDescription(referenceId: string, description: IUserDescription): Promise> { - const url = `${this.config.serverUrl}/api/v2/events/by-ref/${encodeURIComponent(referenceId)}/user-description`; + public async submitUserDescription( + referenceId: string, + description: UserDescription, + ): Promise> { + const url = `${this.config.serverUrl}/api/v2/events/by-ref/${ + encodeURIComponent(referenceId) + }/user-description`; const response = await this.fetch(url, { - method: 'POST', - body: JSON.stringify(description) + method: "POST", + body: JSON.stringify(description), }); await this.updateSettingsVersion(response.settingsVersion); return response; } - public async submitHeartbeat(sessionIdOrUserId: string, closeSession: boolean): Promise> { - const url = `${this.config.heartbeatServerUrl}/api/v2/events/session/heartbeat?id=${sessionIdOrUserId}&close=${closeSession}`; + public async submitHeartbeat( + sessionIdOrUserId: string, + closeSession: boolean, + ): Promise> { + const url = + `${this.config.heartbeatServerUrl}/api/v2/events/session/heartbeat?id=${sessionIdOrUserId}&close=${closeSession}`; const response = await this.fetch(url, { - method: 'GET' + method: "GET", }); await this.updateSettingsVersion(response.settingsVersion); return response; } - protected async updateSettingsVersion(settingsVersion: number): Promise { + protected async updateSettingsVersion( + settingsVersion: number, + ): Promise { if (!isNaN(settingsVersion)) { await SettingsManager.checkVersion(settingsVersion, this.config); } else { - this.config.log.error('No config version header was returned.'); + this.config.log.error("No config version header was returned."); } } - protected abstract fetch(url: string, options: FetchOptions): Promise>; + protected abstract fetch( + url: string, + options: FetchOptions, + ): Promise>; } diff --git a/packages/node/src/services/NodeEnvironmentInfoCollector.ts b/packages/node/src/services/NodeEnvironmentInfoCollector.ts index b39f6ed4..d0353a6b 100644 --- a/packages/node/src/services/NodeEnvironmentInfoCollector.ts +++ b/packages/node/src/services/NodeEnvironmentInfoCollector.ts @@ -1,10 +1,4 @@ -import { - argv, - memoryUsage, - pid, - title, - version -} from 'process'; +import { argv, memoryUsage, pid, title, version } from "process"; import { arch, @@ -13,49 +7,49 @@ import { freemem, hostname, loadavg, - networkInterfaces, NetworkInterfaceInfo, + networkInterfaces, platform, release, tmpdir, totalmem, type, - uptime -} from 'os'; + uptime, +} from "os"; import { - IEnvironmentInfo, + EnvironmentInfo, + EventPluginContext, IEnvironmentInfoCollector, - EventPluginContext -} from '@exceptionless/core'; +} from "@exceptionless/core"; export class NodeEnvironmentInfoCollector implements IEnvironmentInfoCollector { - public getEnvironmentInfo(context: EventPluginContext): IEnvironmentInfo { + public getEnvironmentInfo(context: EventPluginContext): EnvironmentInfo { function getIpAddresses(): string { const ips: string[] = []; const interfaces = networkInterfaces(); Object.keys(interfaces).forEach((name) => { interfaces[name].forEach((network: NetworkInterfaceInfo) => { - if ('IPv4' === network.family && !network.internal) { + if ("IPv4" === network.family && !network.internal) { ips.push(network.address); } }); }); - return ips.join(', '); + return ips.join(", "); } if (!cpus) { return null; } - const environmentInfo: IEnvironmentInfo = { + const environmentInfo: EnvironmentInfo = { processor_count: cpus().length, total_physical_memory: totalmem(), available_physical_memory: freemem(), - command_line: argv.join(' '), - process_name: (title || '').replace(/[\uE000-\uF8FF]/g, ''), - process_id: pid + '', + command_line: argv.join(" "), + process_name: (title || "").replace(/[\uE000-\uF8FF]/g, ""), + process_id: pid + "", process_memory_size: memoryUsage().heapTotal, // thread_id: '', architecture: arch(), @@ -67,8 +61,8 @@ export class NodeEnvironmentInfoCollector implements IEnvironmentInfoCollector { loadavg: loadavg(), platform: platform(), tmpdir: tmpdir(), - uptime: uptime() - } + uptime: uptime(), + }, }; const config = context.client.config; diff --git a/packages/node/src/services/NodeErrorParser.ts b/packages/node/src/services/NodeErrorParser.ts index 80d7ac3a..a2a2b5b4 100644 --- a/packages/node/src/services/NodeErrorParser.ts +++ b/packages/node/src/services/NodeErrorParser.ts @@ -1,19 +1,23 @@ -import { parse as fromError } from 'stack-trace' +import { parse as fromError } from "stack-trace"; import { + ErrorInfo, EventPluginContext, - IError, IErrorParser, - IParameter, - IStackFrame -} from '@exceptionless/core'; + ParameterInfo, + StackFrameInfo, +} from "@exceptionless/core"; export class NodeErrorParser implements IErrorParser { - public parse(context: EventPluginContext, exception: Error): Promise { - function getParameters(parameters: string | string[]): IParameter[] { - const params: string[] = (typeof parameters === 'string' ? [parameters] : parameters) || []; - - const items: IParameter[] = []; + public parse( + context: EventPluginContext, + exception: Error, + ): Promise { + function getParameters(parameters: string | string[]): ParameterInfo[] { + const params: string[] = + (typeof parameters === "string" ? [parameters] : parameters) || []; + + const items: ParameterInfo[] = []; for (const param of params) { items.push({ name: param }); } @@ -21,8 +25,8 @@ export class NodeErrorParser implements IErrorParser { return items; } - function getStackFrames(stackFrames: any[]): IStackFrame[] { - const frames: IStackFrame[] = []; + function getStackFrames(stackFrames: any[]): StackFrameInfo[] { + const frames: StackFrameInfo[] = []; for (const frame of stackFrames) { frames.push({ @@ -33,8 +37,10 @@ export class NodeErrorParser implements IErrorParser { column: frame.getColumnNumber() || 0, declaring_type: frame.getTypeName(), data: { - is_native: frame.isNative() || (frame.filename && frame.filename[0] !== '/' && frame.filename[0] !== '.') - } + is_native: frame.isNative() || + (frame.filename && frame.filename[0] !== "/" && + frame.filename[0] !== "."), + }, }); } @@ -43,13 +49,13 @@ export class NodeErrorParser implements IErrorParser { const result = fromError(exception); if (!result) { - throw new Error('Unable to parse the exception stack trace.'); + throw new Error("Unable to parse the exception stack trace."); } return Promise.resolve({ - type: exception.name || 'Error', + type: exception.name || "Error", message: exception.message, - stack_trace: getStackFrames(result || []) + stack_trace: getStackFrames(result || []), }); } } diff --git a/packages/node/src/services/NodeModuleCollector.ts b/packages/node/src/services/NodeModuleCollector.ts index 4868d22c..b69baa43 100644 --- a/packages/node/src/services/NodeModuleCollector.ts +++ b/packages/node/src/services/NodeModuleCollector.ts @@ -1,23 +1,16 @@ -import { spawnSync } from 'child_process' +import { spawnSync } from "child_process"; -import { - dirname, - join, - resolve -} from 'path'; +import { dirname, join, resolve } from "path"; -import { argv } from 'process'; +import { argv } from "process"; -import { - IModule, - IModuleCollector -} from '@exceptionless/core'; +import { IModuleCollector, ModuleInfo } from "@exceptionless/core"; export class NodeModuleCollector implements IModuleCollector { private initialized: boolean = false; - private installedModules: { [id: string]: IModule } = {}; + private installedModules: { [id: string]: ModuleInfo } = {}; - public getModules(): IModule[] { + public getModules(): ModuleInfo[] { if (argv && argv.length < 2) { return []; } @@ -25,7 +18,7 @@ export class NodeModuleCollector implements IModuleCollector { this.initialize(); // TODO: Cache this lookup - const modulePath = resolve(join(dirname(argv[1]), 'node_modules')); + const modulePath = resolve(join(dirname(argv[1]), "node_modules")); // TODO: What to do if this doesn't exist.. console.log(modulePath); const pathLength = modulePath.length; @@ -36,7 +29,7 @@ export class NodeModuleCollector implements IModuleCollector { loadedKeys.forEach((key) => { let id = key.substr(pathLength); - id = id.substr(0, id.indexOf('/')); + id = id.substr(0, id.indexOf("/")); loadedModules[id] = true; }); console.log(loadedKeys, loadedModules, module); @@ -54,7 +47,7 @@ export class NodeModuleCollector implements IModuleCollector { let json: { dependencies?: { version: string }[] }; try { - const output = spawnSync('npm', ['ls', '--depth=0', '--json']).stdout; + const output = spawnSync("npm", ["ls", "--depth=0", "--json"]).stdout; if (!output) { return; } @@ -74,10 +67,10 @@ export class NodeModuleCollector implements IModuleCollector { Object.keys(items).forEach((key) => { const item = items[key]; - const theModule: IModule = { + const theModule: ModuleInfo = { module_id: id++, name: key, - version: item.version + version: item.version, }; this.installedModules[key] = theModule; diff --git a/packages/node/src/services/NodeRequestInfoCollector.ts b/packages/node/src/services/NodeRequestInfoCollector.ts index 42d919b6..29fb94bd 100644 --- a/packages/node/src/services/NodeRequestInfoCollector.ts +++ b/packages/node/src/services/NodeRequestInfoCollector.ts @@ -1,14 +1,14 @@ import { EventPluginContext, - IRequestInfo, - IRequestInfoCollector, getCookies, - stringify -} from '@exceptionless/core'; + IRequestInfoCollector, + RequestInfo, + stringify, +} from "@exceptionless/core"; export class NodeRequestInfoCollector implements IRequestInfoCollector { - public getRequestInfo(context: EventPluginContext): IRequestInfo { - const REQUEST_KEY: string = '@request'; // optimization for minifier. + public getRequestInfo(context: EventPluginContext): RequestInfo { + const REQUEST_KEY: string = "@request"; // optimization for minifier. if (!context.contextData[REQUEST_KEY]) { return null; } @@ -18,16 +18,17 @@ export class NodeRequestInfoCollector implements IRequestInfoCollector { // TODO: include referrer const request = context.contextData[REQUEST_KEY]; - const requestInfo: IRequestInfo = { - user_agent: request.headers['user-agent'], + const requestInfo: RequestInfo = { + user_agent: request.headers["user-agent"], is_secure: request.secure, http_method: request.method, host: request.hostname || request.host, - path: request.path + path: request.path, }; const host = request.headers.host; - const port: number = host && parseInt(host.slice(host.indexOf(':') + 1), 10); + const port: number = host && + parseInt(host.slice(host.indexOf(":") + 1), 10); if (port > 0) { requestInfo.port = port; } @@ -41,11 +42,15 @@ export class NodeRequestInfoCollector implements IRequestInfoCollector { } if (config.includeQueryString) { - requestInfo.query_string = JSON.parse(stringify(request.params || {}, exclusions)); + requestInfo.query_string = JSON.parse( + stringify(request.params || {}, exclusions), + ); } if (config.includePostData) { - requestInfo.post_data = JSON.parse(stringify(request.body || {}, exclusions)); + requestInfo.post_data = JSON.parse( + stringify(request.body || {}, exclusions), + ); } return requestInfo; diff --git a/tsconfig.json b/tsconfig.json index 392daabe..8bec4f51 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,9 @@ "declarationMap": true, "esModuleInterop": true, "forceConsistentCasingInFileNames": true, - "lib": ["ES2020"], + "lib": [ + "ES2020" + ], "module": "ESNext", "moduleResolution": "Node", "noImplicitAny": false, From 4a8195961ed266aeae1a983490faceadaa3e338e Mon Sep 17 00:00:00 2001 From: "Eric J. Smith" Date: Fri, 26 Feb 2021 00:41:23 -0600 Subject: [PATCH 2/2] Combine error models into single file --- .vscode/tasks.json | 2 + packages/core/src/index.ts | 14 ++++--- packages/core/src/models/data/ErrorInfo.ts | 40 +++++++++++++++++++ .../src/models/data/{error => }/ModuleInfo.ts | 0 .../core/src/models/data/error/ErrorInfo.ts | 6 --- .../src/models/data/error/InnerErrorInfo.ts | 12 ------ .../core/src/models/data/error/MethodInfo.ts | 12 ------ .../src/models/data/error/ParameterInfo.ts | 7 ---- .../src/models/data/error/StackFrameInfo.ts | 7 ---- .../plugins/default/DuplicateCheckerPlugin.ts | 2 +- .../plugins/default/EventExclusionPlugin.ts | 2 +- .../src/plugins/default/ModuleInfoPlugin.ts | 2 +- packages/core/src/services/IErrorParser.ts | 2 +- .../core/src/services/IModuleCollector.ts | 2 +- 14 files changed, 55 insertions(+), 55 deletions(-) create mode 100644 packages/core/src/models/data/ErrorInfo.ts rename packages/core/src/models/data/{error => }/ModuleInfo.ts (100%) delete mode 100644 packages/core/src/models/data/error/ErrorInfo.ts delete mode 100644 packages/core/src/models/data/error/InnerErrorInfo.ts delete mode 100644 packages/core/src/models/data/error/MethodInfo.ts delete mode 100644 packages/core/src/models/data/error/ParameterInfo.ts delete mode 100644 packages/core/src/models/data/error/StackFrameInfo.ts diff --git a/.vscode/tasks.json b/.vscode/tasks.json index b40dcb6d..d0115eec 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -6,6 +6,8 @@ { "type": "npm", "script": "clean", + "problemMatcher": [], + "label": "npm: clean" }, { "type": "npm", diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 4fffde7f..fbb0aec1 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -15,13 +15,15 @@ export { ManualStackingInfo } from "./models/data/ManualStackingInfo.js"; export { RequestInfo } from "./models/data/RequestInfo.js"; export { UserDescription } from "./models/data/UserDescription.js"; export { UserInfo } from "./models/data/UserInfo.js"; +export { ModuleInfo } from "./models/data/ModuleInfo.js"; -export { ErrorInfo } from "./models/data/error/ErrorInfo.js"; -export { InnerErrorInfo } from "./models/data/error/InnerErrorInfo.js"; -export { MethodInfo } from "./models/data/error/MethodInfo.js"; -export { ModuleInfo } from "./models/data/error/ModuleInfo.js"; -export { ParameterInfo } from "./models/data/error/ParameterInfo.js"; -export { StackFrameInfo } from "./models/data/error/StackFrameInfo.js"; +export { + ErrorInfo, + InnerErrorInfo, + MethodInfo, + ParameterInfo, + StackFrameInfo, +} from "./models/data/ErrorInfo.js"; export { ConfigurationDefaultsPlugin } from "./plugins/default/ConfigurationDefaultsPlugin.js"; export { DuplicateCheckerPlugin } from "./plugins/default/DuplicateCheckerPlugin.js"; diff --git a/packages/core/src/models/data/ErrorInfo.ts b/packages/core/src/models/data/ErrorInfo.ts new file mode 100644 index 00000000..da8e4785 --- /dev/null +++ b/packages/core/src/models/data/ErrorInfo.ts @@ -0,0 +1,40 @@ +import { ModuleInfo } from "./ModuleInfo.js"; + +export class InnerErrorInfo { + message?: string; + type?: string; + code?: string; + data?: any; + inner?: InnerErrorInfo; + stack_trace?: StackFrameInfo[]; + target_method?: MethodInfo; +} + +export class ErrorInfo extends InnerErrorInfo { + modules?: ModuleInfo[]; +} + +export class MethodInfo { + data?: any; + generic_arguments?: string[]; + parameters?: ParameterInfo[]; + is_signature_target?: boolean; + declaring_namespace?: string; + declaring_type?: string; + name?: string; + module_id?: number; +} + +export class ParameterInfo { + data?: any; + generic_arguments?: string[]; + name?: string; + type?: string; + type_namespace?: string; +} + +export class StackFrameInfo extends MethodInfo { + file_name?: string; + line_number?: number; + column?: number; +} diff --git a/packages/core/src/models/data/error/ModuleInfo.ts b/packages/core/src/models/data/ModuleInfo.ts similarity index 100% rename from packages/core/src/models/data/error/ModuleInfo.ts rename to packages/core/src/models/data/ModuleInfo.ts diff --git a/packages/core/src/models/data/error/ErrorInfo.ts b/packages/core/src/models/data/error/ErrorInfo.ts deleted file mode 100644 index f7cb8342..00000000 --- a/packages/core/src/models/data/error/ErrorInfo.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { InnerErrorInfo } from "./InnerErrorInfo.js"; -import { ModuleInfo } from "./ModuleInfo.js"; - -export class ErrorInfo extends InnerErrorInfo { - modules?: ModuleInfo[]; -} diff --git a/packages/core/src/models/data/error/InnerErrorInfo.ts b/packages/core/src/models/data/error/InnerErrorInfo.ts deleted file mode 100644 index c2ef0314..00000000 --- a/packages/core/src/models/data/error/InnerErrorInfo.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { MethodInfo } from "./MethodInfo.js"; -import { StackFrameInfo } from "./StackFrameInfo.js"; - -export class InnerErrorInfo { - message?: string; - type?: string; - code?: string; - data?: any; - inner?: InnerErrorInfo; - stack_trace?: StackFrameInfo[]; - target_method?: MethodInfo; -} diff --git a/packages/core/src/models/data/error/MethodInfo.ts b/packages/core/src/models/data/error/MethodInfo.ts deleted file mode 100644 index 81736c69..00000000 --- a/packages/core/src/models/data/error/MethodInfo.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ParameterInfo } from "./ParameterInfo.js"; - -export class MethodInfo { - data?: any; - generic_arguments?: string[]; - parameters?: ParameterInfo[]; - is_signature_target?: boolean; - declaring_namespace?: string; - declaring_type?: string; - name?: string; - module_id?: number; -} diff --git a/packages/core/src/models/data/error/ParameterInfo.ts b/packages/core/src/models/data/error/ParameterInfo.ts deleted file mode 100644 index 2bd00383..00000000 --- a/packages/core/src/models/data/error/ParameterInfo.ts +++ /dev/null @@ -1,7 +0,0 @@ -export class ParameterInfo { - data?: any; - generic_arguments?: string[]; - name?: string; - type?: string; - type_namespace?: string; -} diff --git a/packages/core/src/models/data/error/StackFrameInfo.ts b/packages/core/src/models/data/error/StackFrameInfo.ts deleted file mode 100644 index b34deba6..00000000 --- a/packages/core/src/models/data/error/StackFrameInfo.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { MethodInfo } from "./MethodInfo.js"; - -export class StackFrameInfo extends MethodInfo { - file_name?: string; - line_number?: number; - column?: number; -} diff --git a/packages/core/src/plugins/default/DuplicateCheckerPlugin.ts b/packages/core/src/plugins/default/DuplicateCheckerPlugin.ts index ea4be6c7..f753e557 100644 --- a/packages/core/src/plugins/default/DuplicateCheckerPlugin.ts +++ b/packages/core/src/plugins/default/DuplicateCheckerPlugin.ts @@ -1,4 +1,4 @@ -import { InnerErrorInfo } from "../../models/data/error/InnerErrorInfo.js"; +import { InnerErrorInfo } from "../../models/data/ErrorInfo.js"; import { getHashCode } from "../../Utils.js"; import { EventPluginContext } from "../EventPluginContext.js"; import { IEventPlugin } from "../IEventPlugin.js"; diff --git a/packages/core/src/plugins/default/EventExclusionPlugin.ts b/packages/core/src/plugins/default/EventExclusionPlugin.ts index eb522382..583fa93e 100644 --- a/packages/core/src/plugins/default/EventExclusionPlugin.ts +++ b/packages/core/src/plugins/default/EventExclusionPlugin.ts @@ -1,4 +1,4 @@ -import { InnerErrorInfo } from "../../models/data/error/InnerErrorInfo.js"; +import { InnerErrorInfo } from "../../models/data/ErrorInfo.js"; import { isMatch, startsWith, toBoolean } from "../../Utils.js"; import { EventPluginContext } from "../EventPluginContext.js"; import { IEventPlugin } from "../IEventPlugin.js"; diff --git a/packages/core/src/plugins/default/ModuleInfoPlugin.ts b/packages/core/src/plugins/default/ModuleInfoPlugin.ts index 4e0721bb..f23e2e93 100644 --- a/packages/core/src/plugins/default/ModuleInfoPlugin.ts +++ b/packages/core/src/plugins/default/ModuleInfoPlugin.ts @@ -1,4 +1,4 @@ -import { ModuleInfo } from "../../models/data/error/ModuleInfo.js"; +import { ModuleInfo } from "../../models/data/ModuleInfo.js"; import { EventPluginContext } from "../EventPluginContext.js"; import { IEventPlugin } from "../IEventPlugin.js"; diff --git a/packages/core/src/services/IErrorParser.ts b/packages/core/src/services/IErrorParser.ts index 9bcc46f1..c0db6a3d 100644 --- a/packages/core/src/services/IErrorParser.ts +++ b/packages/core/src/services/IErrorParser.ts @@ -1,4 +1,4 @@ -import { ErrorInfo } from "../models/data/error/ErrorInfo.js"; +import { ErrorInfo } from "../models/data/ErrorInfo.js"; import { EventPluginContext } from "../plugins/EventPluginContext.js"; export interface IErrorParser { diff --git a/packages/core/src/services/IModuleCollector.ts b/packages/core/src/services/IModuleCollector.ts index 63abbdf5..c8215d5a 100644 --- a/packages/core/src/services/IModuleCollector.ts +++ b/packages/core/src/services/IModuleCollector.ts @@ -1,4 +1,4 @@ -import { ModuleInfo } from "../models/data/error/ModuleInfo.js"; +import { ModuleInfo } from "../models/data/ModuleInfo.js"; export interface IModuleCollector { getModules(): ModuleInfo[];