@sneat/logging 0.1.2 → 0.1.4
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.
- package/esm2022/index.js +4 -0
- package/esm2022/index.js.map +1 -0
- package/esm2022/lib/analytics/fire-analytics.service.js +68 -0
- package/esm2022/lib/analytics/fire-analytics.service.js.map +1 -0
- package/esm2022/lib/analytics/index.js +2 -0
- package/esm2022/lib/analytics/index.js.map +1 -0
- package/esm2022/lib/analytics/multi-analytics.service.js +21 -0
- package/esm2022/lib/analytics/multi-analytics.service.js.map +1 -0
- package/esm2022/lib/analytics/posthog-analytics.service.js +47 -0
- package/esm2022/lib/analytics/posthog-analytics.service.js.map +1 -0
- package/esm2022/lib/analytics/provide-sneat-analytics.js +46 -0
- package/esm2022/lib/analytics/provide-sneat-analytics.js.map +1 -0
- package/esm2022/lib/error-logger.service.js +109 -0
- package/esm2022/lib/error-logger.service.js.map +1 -0
- package/esm2022/lib/sentry-setup.js +29 -0
- package/esm2022/lib/sentry-setup.js.map +1 -0
- package/esm2022/lib/sneat-logging.module.js +23 -0
- package/esm2022/lib/sneat-logging.module.js.map +1 -0
- package/esm2022/sneat-logging.js +5 -0
- package/esm2022/sneat-logging.js.map +1 -0
- package/lib/analytics/fire-analytics.service.d.ts +14 -0
- package/lib/analytics/multi-analytics.service.d.ts +9 -0
- package/lib/analytics/posthog-analytics.service.d.ts +11 -0
- package/lib/analytics/provide-sneat-analytics.d.ts +7 -0
- package/lib/error-logger.service.d.ts +12 -0
- package/lib/sentry-setup.d.ts +13 -0
- package/lib/sneat-logging.module.d.ts +8 -0
- package/package.json +14 -2
- package/sneat-logging.d.ts +5 -0
- package/eslint.config.js +0 -7
- package/ng-package.json +0 -7
- package/project.json +0 -38
- package/src/lib/analytics/analytics.service.spec.ts +0 -35
- package/src/lib/analytics/fire-analytics.service.spec.ts +0 -245
- package/src/lib/analytics/fire-analytics.service.ts +0 -92
- package/src/lib/analytics/multi-analytics.service.spec.ts +0 -112
- package/src/lib/analytics/multi-analytics.service.ts +0 -47
- package/src/lib/analytics/posthog-analytics.service.spec.ts +0 -123
- package/src/lib/analytics/posthog-analytics.service.ts +0 -46
- package/src/lib/analytics/provide-sneat-analytics.ts +0 -68
- package/src/lib/error-logger.service.spec.ts +0 -284
- package/src/lib/error-logger.service.ts +0 -131
- package/src/lib/sentry-setup.ts +0 -32
- package/src/lib/sneat-logging.module.ts +0 -16
- package/src/test-setup.ts +0 -3
- package/tsconfig.json +0 -13
- package/tsconfig.lib.json +0 -19
- package/tsconfig.lib.prod.json +0 -7
- package/tsconfig.spec.json +0 -31
- package/vite.config.mts +0 -10
- /package/{src/index.ts → index.d.ts} +0 -0
- /package/{src/lib/analytics/index.ts → lib/analytics/index.d.ts} +0 -0
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { Analytics, getAnalytics } from '@angular/fire/analytics';
|
|
2
|
-
import { FirebaseApp } from '@angular/fire/app';
|
|
3
|
-
import {
|
|
4
|
-
AnalyticsService,
|
|
5
|
-
IAnalyticsService,
|
|
6
|
-
IEnvironmentConfig,
|
|
7
|
-
} from '@sneat/core';
|
|
8
|
-
import { ErrorLogger, IErrorLogger } from '@sneat/core';
|
|
9
|
-
import { FireAnalyticsService } from './fire-analytics.service';
|
|
10
|
-
import { MultiAnalyticsService } from './multi-analytics.service';
|
|
11
|
-
import { PosthogAnalyticsService } from './posthog-analytics.service';
|
|
12
|
-
import { Provider } from '@angular/core';
|
|
13
|
-
|
|
14
|
-
export interface IAnalyticsConfig {
|
|
15
|
-
addPosthog?: boolean;
|
|
16
|
-
addFirebaseAnalytics?: boolean;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function getAnalyticsConfig(
|
|
20
|
-
environmentConfig: IEnvironmentConfig,
|
|
21
|
-
): IAnalyticsConfig {
|
|
22
|
-
const useAnalytics =
|
|
23
|
-
location.host === 'sneat.app' || location.protocol === 'https:';
|
|
24
|
-
|
|
25
|
-
const firebaseMeasurementId = environmentConfig.firebaseConfig?.measurementId;
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
addPosthog: useAnalytics && !!environmentConfig.posthog?.token,
|
|
29
|
-
addFirebaseAnalytics:
|
|
30
|
-
useAnalytics &&
|
|
31
|
-
!!firebaseMeasurementId &&
|
|
32
|
-
firebaseMeasurementId !== 'G-PROVIDE_IF_NEEDED',
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function provideSneatAnalytics(
|
|
37
|
-
environmentConfig: IEnvironmentConfig,
|
|
38
|
-
): Provider {
|
|
39
|
-
return {
|
|
40
|
-
provide: AnalyticsService,
|
|
41
|
-
deps: [
|
|
42
|
-
ErrorLogger,
|
|
43
|
-
FirebaseApp,
|
|
44
|
-
// [new Optional(), Analytics], // TODO: The received Analytics instance does not have app property :(
|
|
45
|
-
],
|
|
46
|
-
useFactory: (errorLogger: IErrorLogger, fbApp: FirebaseApp) => {
|
|
47
|
-
const config = getAnalyticsConfig(environmentConfig);
|
|
48
|
-
const as: IAnalyticsService[] = [];
|
|
49
|
-
if (config?.addPosthog) {
|
|
50
|
-
as.push(new PosthogAnalyticsService());
|
|
51
|
-
}
|
|
52
|
-
if (config?.addFirebaseAnalytics) {
|
|
53
|
-
const analytics: Analytics = fbApp && getAnalytics(fbApp); // Ideally we would want to get it from the DI
|
|
54
|
-
if (analytics) {
|
|
55
|
-
as.push(new FireAnalyticsService());
|
|
56
|
-
// as.push(new FireAnalyticsService(errorLogger, analytics));
|
|
57
|
-
} else {
|
|
58
|
-
errorLogger.logError(
|
|
59
|
-
'addFirebaseAnalytics==true, but Firebase Analytics is not provided',
|
|
60
|
-
undefined,
|
|
61
|
-
{ show: false, feedback: false },
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return new MultiAnalyticsService(as);
|
|
66
|
-
},
|
|
67
|
-
};
|
|
68
|
-
}
|
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
import { TestBed } from '@angular/core/testing';
|
|
2
|
-
import { ErrorLoggerService } from './error-logger.service';
|
|
3
|
-
import { ToastController } from '@ionic/angular/standalone';
|
|
4
|
-
import { captureException, showReportDialog } from '@sentry/angular';
|
|
5
|
-
import { HttpErrorResponse } from '@angular/common/http';
|
|
6
|
-
import { Mock } from 'vitest';
|
|
7
|
-
|
|
8
|
-
vi.mock('@sentry/angular', () => ({
|
|
9
|
-
captureException: vi.fn().mockImplementation(() => {
|
|
10
|
-
return 'event-id';
|
|
11
|
-
}),
|
|
12
|
-
showReportDialog: vi.fn(),
|
|
13
|
-
}));
|
|
14
|
-
|
|
15
|
-
describe('ErrorLoggerService', () => {
|
|
16
|
-
let service: ErrorLoggerService;
|
|
17
|
-
let toastController: { create: Mock; dismiss: Mock };
|
|
18
|
-
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
toastController = {
|
|
21
|
-
create: vi.fn().mockReturnValue(
|
|
22
|
-
Promise.resolve({
|
|
23
|
-
present: vi.fn().mockReturnValue(Promise.resolve()),
|
|
24
|
-
}),
|
|
25
|
-
),
|
|
26
|
-
dismiss: vi.fn().mockReturnValue(Promise.resolve()),
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
TestBed.configureTestingModule({
|
|
30
|
-
providers: [
|
|
31
|
-
ErrorLoggerService,
|
|
32
|
-
{ provide: ToastController, useValue: toastController },
|
|
33
|
-
],
|
|
34
|
-
});
|
|
35
|
-
service = TestBed.inject(ErrorLoggerService);
|
|
36
|
-
vi.clearAllMocks();
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('should be created', () => {
|
|
40
|
-
expect(service).toBeTruthy();
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
describe('logError', () => {
|
|
44
|
-
it('should log to console.error', () => {
|
|
45
|
-
const consoleSpy = vi
|
|
46
|
-
.spyOn(console, 'error')
|
|
47
|
-
.mockImplementation(() => undefined);
|
|
48
|
-
service.logError(new Error('test'));
|
|
49
|
-
expect(consoleSpy).toHaveBeenCalled();
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('should NOT capture exception if on localhost', () => {
|
|
53
|
-
vi.stubGlobal('location', { hostname: 'localhost' });
|
|
54
|
-
service.logError(new Error('test'), 'msg', { report: true });
|
|
55
|
-
expect(captureException).not.toHaveBeenCalled();
|
|
56
|
-
vi.unstubAllGlobals();
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
it('should capture exception if NOT on localhost', () => {
|
|
60
|
-
vi.stubGlobal('location', { hostname: 'example.com' });
|
|
61
|
-
service.logError(new Error('test'), 'msg', { report: true });
|
|
62
|
-
expect(captureException).toHaveBeenCalled();
|
|
63
|
-
vi.unstubAllGlobals();
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('should show error toast by default', () => {
|
|
67
|
-
service.logError(new Error('test'));
|
|
68
|
-
expect(toastController.create).toHaveBeenCalled();
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('should handle boolean true value as error', () => {
|
|
72
|
-
const consoleSpy = vi
|
|
73
|
-
.spyOn(console, 'error')
|
|
74
|
-
.mockImplementation(() => undefined);
|
|
75
|
-
service.logError(true, 'test message');
|
|
76
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
77
|
-
expect.stringContaining('Argument exception'),
|
|
78
|
-
expect.any(Error),
|
|
79
|
-
undefined,
|
|
80
|
-
);
|
|
81
|
-
consoleSpy.mockRestore();
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('should handle boolean false value as error', () => {
|
|
85
|
-
const consoleSpy = vi
|
|
86
|
-
.spyOn(console, 'error')
|
|
87
|
-
.mockImplementation(() => undefined);
|
|
88
|
-
service.logError(false, 'test message');
|
|
89
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
90
|
-
expect.stringContaining('Argument exception'),
|
|
91
|
-
expect.any(Error),
|
|
92
|
-
undefined,
|
|
93
|
-
);
|
|
94
|
-
consoleSpy.mockRestore();
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('should not show feedback dialog when feedback is false', () => {
|
|
98
|
-
vi.stubGlobal('location', { hostname: 'example.com' });
|
|
99
|
-
service.logError(new Error('test'), 'msg', {
|
|
100
|
-
report: true,
|
|
101
|
-
feedback: false,
|
|
102
|
-
});
|
|
103
|
-
expect(showReportDialog).not.toHaveBeenCalled();
|
|
104
|
-
vi.unstubAllGlobals();
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it('should show feedback dialog by default when capturing', () => {
|
|
108
|
-
vi.stubGlobal('location', { hostname: 'example.com' });
|
|
109
|
-
service.logError(new Error('test'), 'msg', { report: true });
|
|
110
|
-
expect(showReportDialog).toHaveBeenCalledWith({ eventId: 'event-id' });
|
|
111
|
-
vi.unstubAllGlobals();
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should handle Sentry exception gracefully', () => {
|
|
115
|
-
vi.stubGlobal('location', { hostname: 'example.com' });
|
|
116
|
-
const consoleSpy = vi
|
|
117
|
-
.spyOn(console, 'error')
|
|
118
|
-
.mockImplementation(() => undefined);
|
|
119
|
-
vi.mocked(captureException).mockImplementationOnce(() => {
|
|
120
|
-
throw new Error('Sentry failed');
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
service.logError(new Error('test'), 'msg', { report: true });
|
|
124
|
-
|
|
125
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
126
|
-
expect.stringContaining('Sentry failed'),
|
|
127
|
-
expect.any(Error),
|
|
128
|
-
);
|
|
129
|
-
consoleSpy.mockRestore();
|
|
130
|
-
vi.unstubAllGlobals();
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
it('should not show error when show option is false', () => {
|
|
134
|
-
service.logError(new Error('test'), 'msg', { show: false });
|
|
135
|
-
expect(toastController.create).not.toHaveBeenCalled();
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it('should not report error when report option is false', () => {
|
|
139
|
-
vi.stubGlobal('location', { hostname: 'example.com' });
|
|
140
|
-
service.logError(new Error('test'), 'msg', { report: false });
|
|
141
|
-
expect(captureException).not.toHaveBeenCalled();
|
|
142
|
-
vi.unstubAllGlobals();
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
describe('showError', () => {
|
|
147
|
-
it('should show toast with error message', async () => {
|
|
148
|
-
await service.showError(new Error('test message'));
|
|
149
|
-
expect(toastController.create).toHaveBeenCalledWith(
|
|
150
|
-
expect.objectContaining({
|
|
151
|
-
message: 'test message',
|
|
152
|
-
}),
|
|
153
|
-
);
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('should handle HttpErrorResponse with server message', async () => {
|
|
157
|
-
const errorResponse = new HttpErrorResponse({
|
|
158
|
-
error: { error: { message: 'server fail' } },
|
|
159
|
-
});
|
|
160
|
-
await service.showError(errorResponse);
|
|
161
|
-
expect(toastController.create).toHaveBeenCalledWith(
|
|
162
|
-
expect.objectContaining({
|
|
163
|
-
message: expect.stringContaining('server fail'),
|
|
164
|
-
}),
|
|
165
|
-
);
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
it('should throw error if e is null (results in crash/throw)', () => {
|
|
169
|
-
expect(() => service.showError(null as unknown as string)).toThrow();
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
it('should throw error for negative duration', () => {
|
|
173
|
-
expect(() => service.showError('test', -1)).toThrow();
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
it('should warn when ToastController is not available', () => {
|
|
177
|
-
const consoleSpy = vi
|
|
178
|
-
.spyOn(console, 'warn')
|
|
179
|
-
.mockImplementation(() => undefined);
|
|
180
|
-
TestBed.resetTestingModule();
|
|
181
|
-
TestBed.configureTestingModule({
|
|
182
|
-
providers: [
|
|
183
|
-
ErrorLoggerService,
|
|
184
|
-
{ provide: ToastController, useValue: null },
|
|
185
|
-
],
|
|
186
|
-
});
|
|
187
|
-
const serviceWithoutToast = TestBed.inject(ErrorLoggerService);
|
|
188
|
-
|
|
189
|
-
serviceWithoutToast.showError(new Error('test'));
|
|
190
|
-
|
|
191
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
192
|
-
expect.stringContaining('ToastController not available'),
|
|
193
|
-
);
|
|
194
|
-
consoleSpy.mockRestore();
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
it('should handle toast present failure', async () => {
|
|
198
|
-
const presentError = new Error('present failed');
|
|
199
|
-
toastController.create.mockReturnValue(
|
|
200
|
-
Promise.resolve({
|
|
201
|
-
present: vi.fn().mockReturnValue(Promise.reject(presentError)),
|
|
202
|
-
}),
|
|
203
|
-
);
|
|
204
|
-
const logErrorSpy = vi
|
|
205
|
-
.spyOn(service, 'logError')
|
|
206
|
-
.mockImplementation(() => undefined);
|
|
207
|
-
|
|
208
|
-
await service.showError(new Error('test'));
|
|
209
|
-
|
|
210
|
-
// Wait for async operations
|
|
211
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
212
|
-
|
|
213
|
-
expect(logErrorSpy).toHaveBeenCalledWith(
|
|
214
|
-
presentError,
|
|
215
|
-
'Failed to present toast with error message:',
|
|
216
|
-
{ show: false },
|
|
217
|
-
);
|
|
218
|
-
logErrorSpy.mockRestore();
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
it('should handle toast creation failure', async () => {
|
|
222
|
-
const createError = new Error('create failed');
|
|
223
|
-
toastController.create.mockReturnValue(Promise.reject(createError));
|
|
224
|
-
const logErrorSpy = vi
|
|
225
|
-
.spyOn(service, 'logError')
|
|
226
|
-
.mockImplementation(() => undefined);
|
|
227
|
-
|
|
228
|
-
await service.showError(new Error('test'));
|
|
229
|
-
|
|
230
|
-
// Wait for async operations
|
|
231
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
232
|
-
|
|
233
|
-
expect(logErrorSpy).toHaveBeenCalledWith(
|
|
234
|
-
createError,
|
|
235
|
-
'Failed to create a toast with error message:',
|
|
236
|
-
{ show: false },
|
|
237
|
-
);
|
|
238
|
-
logErrorSpy.mockRestore();
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
it('should handle toast dismiss failure in button handler', async () => {
|
|
242
|
-
const dismissError = new Error('dismiss failed');
|
|
243
|
-
toastController.dismiss.mockReturnValue(Promise.reject(dismissError));
|
|
244
|
-
const logErrorSpy = vi
|
|
245
|
-
.spyOn(service, 'logError')
|
|
246
|
-
.mockImplementation(() => undefined);
|
|
247
|
-
|
|
248
|
-
await service.showError(new Error('test'));
|
|
249
|
-
|
|
250
|
-
const createCall = toastController.create.mock.calls[0][0];
|
|
251
|
-
const closeButtonHandler = createCall.buttons[0].handler;
|
|
252
|
-
await closeButtonHandler();
|
|
253
|
-
|
|
254
|
-
expect(logErrorSpy).toHaveBeenCalledWith(
|
|
255
|
-
dismissError,
|
|
256
|
-
'Failed to dismiss error dialog',
|
|
257
|
-
{ show: false },
|
|
258
|
-
);
|
|
259
|
-
logErrorSpy.mockRestore();
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
it('should use custom duration when provided', async () => {
|
|
263
|
-
const customDuration = 5000;
|
|
264
|
-
await service.showError(new Error('test'), customDuration);
|
|
265
|
-
|
|
266
|
-
expect(toastController.create).toHaveBeenCalledWith(
|
|
267
|
-
expect.objectContaining({
|
|
268
|
-
duration: customDuration,
|
|
269
|
-
}),
|
|
270
|
-
);
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
describe('logErrorHandler', () => {
|
|
275
|
-
it('should return a function that calls logError', () => {
|
|
276
|
-
const logSpy = vi
|
|
277
|
-
.spyOn(service, 'logError')
|
|
278
|
-
.mockImplementation(() => undefined);
|
|
279
|
-
const handler = service.logErrorHandler('test msg');
|
|
280
|
-
handler('error');
|
|
281
|
-
expect(logSpy).toHaveBeenCalledWith('error', 'test msg', undefined);
|
|
282
|
-
});
|
|
283
|
-
});
|
|
284
|
-
});
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { HttpErrorResponse } from '@angular/common/http';
|
|
2
|
-
import { Injectable, Optional } from '@angular/core';
|
|
3
|
-
import { ToastController } from '@ionic/angular/standalone';
|
|
4
|
-
import { captureException, showReportDialog } from '@sentry/angular';
|
|
5
|
-
import { IErrorLogger, ILogErrorOptions } from '@sneat/core';
|
|
6
|
-
|
|
7
|
-
const defaultErrorToastDuration = 7000;
|
|
8
|
-
|
|
9
|
-
@Injectable()
|
|
10
|
-
export class ErrorLoggerService implements IErrorLogger {
|
|
11
|
-
constructor(@Optional() private readonly toastController: ToastController) {}
|
|
12
|
-
|
|
13
|
-
public readonly logErrorHandler =
|
|
14
|
-
(message?: string, options?: ILogErrorOptions) => (e: unknown) =>
|
|
15
|
-
this.logError(e, message, options);
|
|
16
|
-
|
|
17
|
-
public readonly logError = (
|
|
18
|
-
e: unknown,
|
|
19
|
-
message?: string,
|
|
20
|
-
options?: ILogErrorOptions,
|
|
21
|
-
): void => {
|
|
22
|
-
console.error(
|
|
23
|
-
`ErrorLoggerService.logError: ${message || 'Error'}:`,
|
|
24
|
-
e,
|
|
25
|
-
'; Logging options:',
|
|
26
|
-
options,
|
|
27
|
-
);
|
|
28
|
-
if (e === true || e === false) {
|
|
29
|
-
try {
|
|
30
|
-
// noinspection ExceptionCaughtLocallyJS
|
|
31
|
-
throw new Error(`got boolean value as an error: ${e}: ${message}`);
|
|
32
|
-
} catch (ex) {
|
|
33
|
-
console.error('Argument exception at logError():', ex, options);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
if (options?.report === undefined || options.report) {
|
|
38
|
-
if (window.location.hostname !== 'localhost') {
|
|
39
|
-
try {
|
|
40
|
-
const eventId = message
|
|
41
|
-
? captureException(message, { originalException: e })
|
|
42
|
-
: captureException(e);
|
|
43
|
-
|
|
44
|
-
// console.log('Captured error by Sentry with eventId:', eventId);
|
|
45
|
-
if (options?.feedback === undefined || options.feedback) {
|
|
46
|
-
showReportDialog({ eventId });
|
|
47
|
-
}
|
|
48
|
-
} catch (ex) {
|
|
49
|
-
console.error(
|
|
50
|
-
'Sentry failed to capture or show error report dialog',
|
|
51
|
-
ex,
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
if (options?.show || options?.show === undefined) {
|
|
57
|
-
this.showError(e, options?.showDuration);
|
|
58
|
-
}
|
|
59
|
-
return; // return message ? { error: e, message } : e;
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
public showError(e: unknown, duration?: number): void {
|
|
63
|
-
let clientMessage: string | undefined;
|
|
64
|
-
|
|
65
|
-
if ((e as { message?: string }).message) {
|
|
66
|
-
clientMessage =
|
|
67
|
-
(clientMessage &&
|
|
68
|
-
`${clientMessage}: ${(e as { message?: string }).message}`) ||
|
|
69
|
-
(e as { message?: string }).message;
|
|
70
|
-
} else if (!clientMessage) {
|
|
71
|
-
clientMessage = (e as object).toString();
|
|
72
|
-
}
|
|
73
|
-
if (!clientMessage) {
|
|
74
|
-
throw new Error('showError() have not received a message to display');
|
|
75
|
-
}
|
|
76
|
-
if (duration && duration < 0) {
|
|
77
|
-
throw new Error('showError received negative duration');
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
let message = clientMessage;
|
|
81
|
-
|
|
82
|
-
let serverMessage: string | undefined;
|
|
83
|
-
if (e instanceof HttpErrorResponse) {
|
|
84
|
-
const e2 = e as HttpErrorResponse;
|
|
85
|
-
serverMessage = e2.error?.error?.message;
|
|
86
|
-
if (serverMessage) {
|
|
87
|
-
message += `.\n\nServer returned error message: ${serverMessage}`;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
if (!this.toastController) {
|
|
91
|
-
console.warn('ToastController not available, cannot show error toast');
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
this.toastController
|
|
95
|
-
.create({
|
|
96
|
-
message,
|
|
97
|
-
duration: duration || defaultErrorToastDuration,
|
|
98
|
-
keyboardClose: true,
|
|
99
|
-
buttons: [
|
|
100
|
-
{
|
|
101
|
-
icon: 'close',
|
|
102
|
-
side: 'end',
|
|
103
|
-
handler: () =>
|
|
104
|
-
this.toastController.dismiss().catch((e) =>
|
|
105
|
-
this.logError(e, 'Failed to dismiss error dialog', {
|
|
106
|
-
show: false,
|
|
107
|
-
}),
|
|
108
|
-
),
|
|
109
|
-
},
|
|
110
|
-
],
|
|
111
|
-
color: 'danger',
|
|
112
|
-
header: 'Something went wrong',
|
|
113
|
-
position: 'top',
|
|
114
|
-
})
|
|
115
|
-
.then((toast) =>
|
|
116
|
-
toast
|
|
117
|
-
.present()
|
|
118
|
-
.catch(
|
|
119
|
-
this.logErrorHandler(
|
|
120
|
-
'Failed to present toast with error message:',
|
|
121
|
-
{ show: false },
|
|
122
|
-
),
|
|
123
|
-
),
|
|
124
|
-
)
|
|
125
|
-
.catch(
|
|
126
|
-
this.logErrorHandler('Failed to create a toast with error message:', {
|
|
127
|
-
show: false,
|
|
128
|
-
}),
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
}
|
package/src/lib/sentry-setup.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { inject, provideAppInitializer, ErrorHandler } from '@angular/core';
|
|
2
|
-
import { TraceService, init, createErrorHandler } from '@sentry/angular';
|
|
3
|
-
import { Router } from '@angular/router';
|
|
4
|
-
import { BrowserOptions } from '@sentry/browser';
|
|
5
|
-
|
|
6
|
-
export const provideSentryAppInitializer = (options: BrowserOptions) => {
|
|
7
|
-
initSentry(options);
|
|
8
|
-
return [
|
|
9
|
-
...sentryAppInitializerProviders,
|
|
10
|
-
provideAppInitializer(() => {
|
|
11
|
-
inject(TraceService);
|
|
12
|
-
}),
|
|
13
|
-
];
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
function initSentry(options: BrowserOptions): void {
|
|
17
|
-
// console.log('initSentry()');
|
|
18
|
-
init(options);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const sentryAppInitializerProviders = [
|
|
22
|
-
{
|
|
23
|
-
provide: TraceService,
|
|
24
|
-
deps: [Router],
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
provide: ErrorHandler,
|
|
28
|
-
useValue: createErrorHandler({
|
|
29
|
-
showDialog: true,
|
|
30
|
-
}),
|
|
31
|
-
},
|
|
32
|
-
];
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { NgModule, Provider } from '@angular/core';
|
|
2
|
-
import { ErrorLogger } from '@sneat/core';
|
|
3
|
-
import { ErrorLoggerService } from './error-logger.service';
|
|
4
|
-
|
|
5
|
-
export function provideErrorLogger(): Provider {
|
|
6
|
-
return {
|
|
7
|
-
provide: ErrorLogger,
|
|
8
|
-
useClass: ErrorLoggerService,
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
@NgModule({
|
|
13
|
-
imports: [],
|
|
14
|
-
providers: [provideErrorLogger()],
|
|
15
|
-
})
|
|
16
|
-
export class SneatLoggingModule {}
|
package/src/test-setup.ts
DELETED
package/tsconfig.json
DELETED
package/tsconfig.lib.json
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../../tsconfig.lib.base.json",
|
|
3
|
-
"exclude": [
|
|
4
|
-
"vite.config.ts",
|
|
5
|
-
"vite.config.mts",
|
|
6
|
-
"vitest.config.ts",
|
|
7
|
-
"vitest.config.mts",
|
|
8
|
-
"src/**/*.test.ts",
|
|
9
|
-
"src/**/*.spec.ts",
|
|
10
|
-
"src/**/*.test.tsx",
|
|
11
|
-
"src/**/*.spec.tsx",
|
|
12
|
-
"src/**/*.test.js",
|
|
13
|
-
"src/**/*.spec.js",
|
|
14
|
-
"src/**/*.test.jsx",
|
|
15
|
-
"src/**/*.spec.jsx",
|
|
16
|
-
"src/test-setup.ts",
|
|
17
|
-
"src/lib/testing/**/*"
|
|
18
|
-
]
|
|
19
|
-
}
|
package/tsconfig.lib.prod.json
DELETED
package/tsconfig.spec.json
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "./tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"outDir": "../../dist/out-tsc",
|
|
5
|
-
"types": [
|
|
6
|
-
"vitest/globals",
|
|
7
|
-
"vitest/importMeta",
|
|
8
|
-
"vite/client",
|
|
9
|
-
"node",
|
|
10
|
-
"vitest"
|
|
11
|
-
]
|
|
12
|
-
},
|
|
13
|
-
"include": [
|
|
14
|
-
"vite.config.ts",
|
|
15
|
-
"vite.config.mts",
|
|
16
|
-
"vitest.config.ts",
|
|
17
|
-
"vitest.config.mts",
|
|
18
|
-
"src/**/*.test.ts",
|
|
19
|
-
"src/**/*.spec.ts",
|
|
20
|
-
"src/**/*.test.tsx",
|
|
21
|
-
"src/**/*.spec.tsx",
|
|
22
|
-
"src/**/*.test.js",
|
|
23
|
-
"src/**/*.spec.js",
|
|
24
|
-
"src/**/*.test.jsx",
|
|
25
|
-
"src/**/*.spec.jsx",
|
|
26
|
-
"src/**/*.d.ts"
|
|
27
|
-
],
|
|
28
|
-
"files": [
|
|
29
|
-
"src/test-setup.ts"
|
|
30
|
-
]
|
|
31
|
-
}
|
package/vite.config.mts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/// <reference types='vitest' />
|
|
2
|
-
import { defineConfig } from 'vitest/config';
|
|
3
|
-
import { createBaseViteConfig } from '../../vite.config.base';
|
|
4
|
-
|
|
5
|
-
export default defineConfig(() =>
|
|
6
|
-
createBaseViteConfig({
|
|
7
|
-
dirname: __dirname,
|
|
8
|
-
name: 'logging',
|
|
9
|
-
}),
|
|
10
|
-
);
|
|
File without changes
|
|
File without changes
|