@servicetitan/log-service 34.2.0 → 34.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -87,9 +87,9 @@ export class GlobalErrorHandler {
87
87
  err.code = 'NonUniform';
88
88
  }
89
89
  if (isUnhandled) {
90
- var _err_code;
91
- err.category = 'UnhandledError';
92
- err.code = (_err_code = err.code) !== null && _err_code !== void 0 ? _err_code : 'UnhandledError';
90
+ var _err, _category, _err1, _code;
91
+ (_category = (_err = err).category) !== null && _category !== void 0 ? _category : _err.category = 'UnhandledError';
92
+ (_code = (_err1 = err).code) !== null && _code !== void 0 ? _code : _err1.code = 'UnhandledError';
93
93
  }
94
94
  this.dispatch(err);
95
95
  } catch (e) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/global-error-handler.ts"],"sourcesContent":["import { inject, injectable } from '@servicetitan/react-ioc';\nimport { ArbitraryData, Log } from './log';\nimport { serializeWithMetadata } from './serialize-with-metadata';\n\ninterface ExtendedError extends Error {\n category?: string;\n code?: string;\n data?: ArbitraryData;\n stack?: string;\n}\n\n@injectable()\nexport class GlobalErrorHandler {\n constructor(@inject(Log) private readonly logService: Log) {}\n\n instrument(window: Window) {\n consolidate(window, 'onerror', this.onError);\n consolidate(window, 'onunhandledrejection', this.onReject);\n }\n\n onError = (\n message: string,\n url?: string,\n line?: number,\n column?: number,\n error?: Error,\n isUnhandled = true\n ) => {\n try {\n if (this.isIgnorable(message)) {\n return;\n }\n let msg = '';\n if (typeof message === 'string') {\n msg = message;\n } else {\n /*\n * By specification message is always a string\n * this condition covers manual nonuniform window.onerror call\n */\n msg = serializeWithMetadata(message);\n }\n\n let err: ExtendedError;\n if (error instanceof Error) {\n err = error;\n } else {\n const errorMessage = `Message - ${msg}${\n error ? ';Error - ' + serializeWithMetadata(error) : ''\n }`;\n err = new Error(errorMessage);\n err.stack += `\\n\\tat somewhere (${url}:${line}:${column})`;\n err.code = 'NonUniform';\n }\n if (isUnhandled) {\n err.category = 'UnhandledError';\n err.code = err.code ?? 'UnhandledError';\n }\n\n this.dispatch(err);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error('@log-service/onError/failsafe', message);\n // eslint-disable-next-line no-console\n console.error('@log-service/onError/failsafe', e);\n }\n };\n\n onReject = (event: { reason: unknown }) => {\n try {\n const error = event.reason;\n let err: ExtendedError;\n if (error instanceof Error) {\n err = error;\n } else {\n const errorMessage = `Unhandled rejection - ${serializeWithMetadata(error)}`;\n err = new Error(errorMessage);\n err.code = 'NonUniform';\n }\n\n this.dispatch(err);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error('@log-service/onReject/failsafe', e);\n }\n };\n\n private dispatch(error: ExtendedError) {\n this.logService.error(\n {\n error,\n category: error.category,\n code: error.code,\n message: error.message,\n data: error.data,\n },\n { skipConsole: true }\n );\n }\n\n private isIgnorable(message: string) {\n if (typeof message !== 'string') {\n return false;\n }\n\n const ignoreSubstrings = [\n // 'Script error.', // cross-domain\n 'gCrWeb',\n 'Geolocation',\n 'kCLErrorDomain',\n 'The last location provider was disabled',\n 'Location services are disabled',\n ];\n\n return ignoreSubstrings.some(sub => message.includes(sub));\n }\n}\n\nfunction consolidate(object: { [key: string]: any }, methodName: string, fn: Function) {\n if (typeof object[methodName] === 'function') {\n const fnPrev = object[methodName];\n\n object[methodName] = (...args: unknown[]) => {\n try {\n fn(...args);\n } finally {\n fnPrev(...args);\n }\n };\n return;\n }\n if (object[methodName] != null) {\n throw new TypeError('attempt to instrument non-function value');\n }\n\n object[methodName] = fn;\n}\n"],"names":["inject","injectable","Log","serializeWithMetadata","GlobalErrorHandler","instrument","window","consolidate","onError","onReject","dispatch","error","logService","category","code","message","data","skipConsole","isIgnorable","ignoreSubstrings","some","sub","includes","url","line","column","isUnhandled","msg","err","Error","errorMessage","stack","e","console","event","reason","object","methodName","fn","fnPrev","args","TypeError"],"mappings":"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"}
1
+ {"version":3,"sources":["../src/global-error-handler.ts"],"sourcesContent":["import { inject, injectable } from '@servicetitan/react-ioc';\nimport { ArbitraryData, Log } from './log';\nimport { serializeWithMetadata } from './serialize-with-metadata';\n\ninterface ExtendedError extends Error {\n category?: string;\n code?: string;\n data?: ArbitraryData;\n stack?: string;\n}\n\n@injectable()\nexport class GlobalErrorHandler {\n constructor(@inject(Log) private readonly logService: Log) {}\n\n instrument(window: Window) {\n consolidate(window, 'onerror', this.onError);\n consolidate(window, 'onunhandledrejection', this.onReject);\n }\n\n onError = (\n message: string,\n url?: string,\n line?: number,\n column?: number,\n error?: Error,\n isUnhandled = true\n ) => {\n try {\n if (this.isIgnorable(message)) {\n return;\n }\n let msg = '';\n if (typeof message === 'string') {\n msg = message;\n } else {\n /*\n * By specification message is always a string\n * this condition covers manual nonuniform window.onerror call\n */\n msg = serializeWithMetadata(message);\n }\n\n let err: ExtendedError;\n if (error instanceof Error) {\n err = error;\n } else {\n const errorMessage = `Message - ${msg}${\n error ? ';Error - ' + serializeWithMetadata(error) : ''\n }`;\n err = new Error(errorMessage);\n err.stack += `\\n\\tat somewhere (${url}:${line}:${column})`;\n err.code = 'NonUniform';\n }\n if (isUnhandled) {\n err.category ??= 'UnhandledError';\n err.code ??= 'UnhandledError';\n }\n\n this.dispatch(err);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error('@log-service/onError/failsafe', message);\n // eslint-disable-next-line no-console\n console.error('@log-service/onError/failsafe', e);\n }\n };\n\n onReject = (event: { reason: unknown }) => {\n try {\n const error = event.reason;\n let err: ExtendedError;\n if (error instanceof Error) {\n err = error;\n } else {\n const errorMessage = `Unhandled rejection - ${serializeWithMetadata(error)}`;\n err = new Error(errorMessage);\n err.code = 'NonUniform';\n }\n\n this.dispatch(err);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error('@log-service/onReject/failsafe', e);\n }\n };\n\n private dispatch(error: ExtendedError) {\n this.logService.error(\n {\n error,\n category: error.category,\n code: error.code,\n message: error.message,\n data: error.data,\n },\n { skipConsole: true }\n );\n }\n\n private isIgnorable(message: string) {\n if (typeof message !== 'string') {\n return false;\n }\n\n const ignoreSubstrings = [\n // 'Script error.', // cross-domain\n 'gCrWeb',\n 'Geolocation',\n 'kCLErrorDomain',\n 'The last location provider was disabled',\n 'Location services are disabled',\n ];\n\n return ignoreSubstrings.some(sub => message.includes(sub));\n }\n}\n\nfunction consolidate(object: { [key: string]: any }, methodName: string, fn: Function) {\n if (typeof object[methodName] === 'function') {\n const fnPrev = object[methodName];\n\n object[methodName] = (...args: unknown[]) => {\n try {\n fn(...args);\n } finally {\n fnPrev(...args);\n }\n };\n return;\n }\n if (object[methodName] != null) {\n throw new TypeError('attempt to instrument non-function value');\n }\n\n object[methodName] = fn;\n}\n"],"names":["inject","injectable","Log","serializeWithMetadata","GlobalErrorHandler","instrument","window","consolidate","onError","onReject","dispatch","error","logService","category","code","message","data","skipConsole","isIgnorable","ignoreSubstrings","some","sub","includes","url","line","column","isUnhandled","msg","err","Error","errorMessage","stack","e","console","event","reason","object","methodName","fn","fnPrev","args","TypeError"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/log-service",
3
- "version": "34.2.0",
3
+ "version": "34.3.0",
4
4
  "description": "Service to send events to Kibana logs via the backend log service",
5
5
  "homepage": "https://docs.st.dev/docs/frontend/uikit/log-service",
6
6
  "repository": {
@@ -16,16 +16,16 @@
16
16
  "src"
17
17
  ],
18
18
  "devDependencies": {
19
- "@servicetitan/react-ioc": "34.2.0",
19
+ "@servicetitan/react-ioc": "34.3.0",
20
20
  "@testing-library/dom": "^10.4.1",
21
21
  "@testing-library/react": "^16.3.2",
22
22
  "@types/lodash.throttle": "~4.1.6",
23
- "axios": "^1.13.5",
23
+ "axios": "^1.13.6",
24
24
  "mobx": "~6.13.7",
25
25
  "react": "~18.3.1"
26
26
  },
27
27
  "peerDependencies": {
28
- "@servicetitan/react-ioc": "34.2.0",
28
+ "@servicetitan/react-ioc": "34.3.0",
29
29
  "axios": ">=0.30.0 <1 || ^1.8.3",
30
30
  "mobx": ">=6.13.7",
31
31
  "react": ">=17.0.2"
@@ -39,5 +39,5 @@
39
39
  "cli": {
40
40
  "webpack": false
41
41
  },
42
- "gitHead": "746e475f7514c9591d68cd71eda974b4d1b275a3"
42
+ "gitHead": "0ca13bccd0abdbcbda28f08829ef38bde4caa927"
43
43
  }
@@ -148,6 +148,31 @@ describe(`[log-service] ${GlobalErrorHandler.name}`, () => {
148
148
  );
149
149
  });
150
150
  });
151
+
152
+ describe('with existing readonly error.code and error.category', () => {
153
+ const code = 401;
154
+ const category = 'foo';
155
+
156
+ class MockError extends Error {
157
+ get category() {
158
+ return category;
159
+ }
160
+ get code() {
161
+ return code;
162
+ }
163
+ }
164
+
165
+ beforeEach(() => (error = new MockError()));
166
+
167
+ test('preserves existing values', () => {
168
+ subject();
169
+
170
+ expect(log.error).toHaveBeenCalledWith(
171
+ expect.objectContaining({ category, code }),
172
+ expect.anything()
173
+ );
174
+ });
175
+ });
151
176
  });
152
177
 
153
178
  describe('onReject', () => {
@@ -53,8 +53,8 @@ export class GlobalErrorHandler {
53
53
  err.code = 'NonUniform';
54
54
  }
55
55
  if (isUnhandled) {
56
- err.category = 'UnhandledError';
57
- err.code = err.code ?? 'UnhandledError';
56
+ err.category ??= 'UnhandledError';
57
+ err.code ??= 'UnhandledError';
58
58
  }
59
59
 
60
60
  this.dispatch(err);