@etsoo/appscript 1.4.73 → 1.4.75
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/lib/cjs/app/CoreApp.d.ts +6 -1
- package/lib/cjs/app/CoreApp.js +35 -6
- package/lib/cjs/app/IApp.d.ts +6 -1
- package/lib/cjs/business/ShoppingCart.js +3 -3
- package/lib/cjs/i18n/en.json +1 -0
- package/lib/cjs/i18n/zh-Hans.json +1 -0
- package/lib/cjs/i18n/zh-Hant.json +1 -0
- package/lib/mjs/app/CoreApp.d.ts +6 -1
- package/lib/mjs/app/CoreApp.js +35 -6
- package/lib/mjs/app/IApp.d.ts +6 -1
- package/lib/mjs/business/ShoppingCart.js +3 -3
- package/lib/mjs/i18n/en.json +1 -0
- package/lib/mjs/i18n/zh-Hans.json +1 -0
- package/lib/mjs/i18n/zh-Hant.json +1 -0
- package/package.json +13 -13
- package/src/app/CoreApp.ts +39 -4
- package/src/app/IApp.ts +7 -0
- package/src/business/ShoppingCart.ts +3 -3
- package/src/i18n/en.json +1 -0
- package/src/i18n/zh-Hans.json +1 -0
- package/src/i18n/zh-Hant.json +1 -0
package/lib/cjs/app/CoreApp.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { INotifier, NotificationAlign, NotificationCallProps, NotificationContent, NotificationReturn } from '@etsoo/notificationbase';
|
|
2
2
|
import { ApiDataError, IApi, IPData } from '@etsoo/restclient';
|
|
3
|
-
import { DataTypes, DateUtils, IActionResult, IStorage, ListType, ListType1 } from '@etsoo/shared';
|
|
3
|
+
import { DataTypes, DateUtils, ErrorData, IActionResult, IStorage, ListType, ListType1 } from '@etsoo/shared';
|
|
4
4
|
import { AddressRegion } from '../address/AddressRegion';
|
|
5
5
|
import { EntityStatus } from '../business/EntityStatus';
|
|
6
6
|
import { InitCallDto } from '../erp/dto/InitCallDto';
|
|
@@ -189,6 +189,11 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
|
|
|
189
189
|
* @param api Api
|
|
190
190
|
*/
|
|
191
191
|
setApiLoading(api: IApi): void;
|
|
192
|
+
/**
|
|
193
|
+
* Setup frontend logging
|
|
194
|
+
* @param action Custom action
|
|
195
|
+
*/
|
|
196
|
+
setupLogging(action?: (data: ErrorData) => void | Promise<void>): void;
|
|
192
197
|
/**
|
|
193
198
|
* Api init call
|
|
194
199
|
* @param data Data
|
package/lib/cjs/app/CoreApp.js
CHANGED
|
@@ -306,6 +306,7 @@ class CoreApp {
|
|
|
306
306
|
? api.transformResponse(error.response).status
|
|
307
307
|
: undefined;
|
|
308
308
|
if (status === 401) {
|
|
309
|
+
// Unauthorized
|
|
309
310
|
if (handlerFor401 === false)
|
|
310
311
|
return;
|
|
311
312
|
if (typeof handlerFor401 === 'function') {
|
|
@@ -316,6 +317,17 @@ class CoreApp {
|
|
|
316
317
|
}
|
|
317
318
|
return;
|
|
318
319
|
}
|
|
320
|
+
else if (error.response == null &&
|
|
321
|
+
(error.message === 'Network Error' ||
|
|
322
|
+
error.message === 'Failed to fetch')) {
|
|
323
|
+
// Network error
|
|
324
|
+
this.notifier.alert(this.get('networkError'));
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
// Log
|
|
329
|
+
console.error('API error', error);
|
|
330
|
+
}
|
|
319
331
|
// Report the error
|
|
320
332
|
this.notifier.alert(this.formatError(error));
|
|
321
333
|
};
|
|
@@ -339,6 +351,23 @@ class CoreApp {
|
|
|
339
351
|
this.lastCalled = true;
|
|
340
352
|
};
|
|
341
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* Setup frontend logging
|
|
356
|
+
* @param action Custom action
|
|
357
|
+
*/
|
|
358
|
+
setupLogging(action) {
|
|
359
|
+
action !== null && action !== void 0 ? action : (action = (data) => {
|
|
360
|
+
this.api.post('Auth/LogFrontendError', data, {
|
|
361
|
+
onError: (error) => {
|
|
362
|
+
// Use 'debug' to avoid infinite loop
|
|
363
|
+
console.debug('Log front-end error', data, error);
|
|
364
|
+
// Prevent global error handler
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
shared_1.DomUtils.setupLogging(action);
|
|
370
|
+
}
|
|
342
371
|
/**
|
|
343
372
|
* Api init call
|
|
344
373
|
* @param data Data
|
|
@@ -650,7 +679,7 @@ class CoreApp {
|
|
|
650
679
|
const iv = enc.Hex.parse(messageEncrypted.substring(34, 66));
|
|
651
680
|
const encrypted = messageEncrypted.substring(66);
|
|
652
681
|
const key = PBKDF2(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, salt, {
|
|
653
|
-
keySize: 8,
|
|
682
|
+
keySize: 8, // 256 / 32
|
|
654
683
|
hasher: algo.SHA256,
|
|
655
684
|
iterations: 1000 * iterations
|
|
656
685
|
});
|
|
@@ -661,7 +690,7 @@ class CoreApp {
|
|
|
661
690
|
}).toString(enc.Utf8);
|
|
662
691
|
}
|
|
663
692
|
catch (e) {
|
|
664
|
-
console.
|
|
693
|
+
console.error(`CoreApp.decrypt ${messageEncrypted} error`, e);
|
|
665
694
|
return undefined;
|
|
666
695
|
}
|
|
667
696
|
}
|
|
@@ -696,7 +725,7 @@ class CoreApp {
|
|
|
696
725
|
return this.decrypt(message, passphrase);
|
|
697
726
|
}
|
|
698
727
|
catch (e) {
|
|
699
|
-
console.
|
|
728
|
+
console.error(`CoreApp.decryptEnhanced ${messageEncrypted} error`, e);
|
|
700
729
|
return undefined;
|
|
701
730
|
}
|
|
702
731
|
}
|
|
@@ -776,7 +805,7 @@ class CoreApp {
|
|
|
776
805
|
const bits = 16; // 128 / 8
|
|
777
806
|
const salt = lib.WordArray.random(bits);
|
|
778
807
|
const key = PBKDF2(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, salt, {
|
|
779
|
-
keySize: 8,
|
|
808
|
+
keySize: 8, // 256 / 32
|
|
780
809
|
hasher: algo.SHA256,
|
|
781
810
|
iterations: 1000 * iterations
|
|
782
811
|
});
|
|
@@ -864,7 +893,7 @@ class CoreApp {
|
|
|
864
893
|
* @returns Error message
|
|
865
894
|
*/
|
|
866
895
|
formatError(error) {
|
|
867
|
-
return error.
|
|
896
|
+
return `${error.message} (${error.name})`;
|
|
868
897
|
}
|
|
869
898
|
/**
|
|
870
899
|
* Refresh token failed
|
|
@@ -1311,7 +1340,7 @@ class CoreApp {
|
|
|
1311
1340
|
async signout() {
|
|
1312
1341
|
await this.api.put('User/Signout', { deviceId: this.deviceId }, {
|
|
1313
1342
|
onError: (error) => {
|
|
1314
|
-
console.
|
|
1343
|
+
console.error('CoreApp.signout error', error);
|
|
1315
1344
|
// Prevent further processing
|
|
1316
1345
|
return false;
|
|
1317
1346
|
}
|
package/lib/cjs/app/IApp.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { INotifier, NotificationAlign, NotificationCallProps, NotificationContent, NotificationReturn } from '@etsoo/notificationbase';
|
|
2
2
|
import { ApiDataError, IApi, IPData } from '@etsoo/restclient';
|
|
3
|
-
import { DataTypes, DateUtils, IActionResult, IStorage, ListType, ListType1 } from '@etsoo/shared';
|
|
3
|
+
import { DataTypes, DateUtils, ErrorData, IActionResult, IStorage, ListType, ListType1 } from '@etsoo/shared';
|
|
4
4
|
import { AddressRegion } from '../address/AddressRegion';
|
|
5
5
|
import { IUser } from '../state/User';
|
|
6
6
|
import { IAppSettings } from './AppSettings';
|
|
@@ -459,6 +459,11 @@ export interface IApp {
|
|
|
459
459
|
* @param api Api
|
|
460
460
|
*/
|
|
461
461
|
setApiLoading(api: IApi): void;
|
|
462
|
+
/**
|
|
463
|
+
* Setup frontend logging
|
|
464
|
+
* @param action Custom action
|
|
465
|
+
*/
|
|
466
|
+
setupLogging(action?: (data: ErrorData) => void | Promise<void>): void;
|
|
462
467
|
/**
|
|
463
468
|
* Signout, with userLogout and toLoginPage
|
|
464
469
|
*/
|
|
@@ -31,7 +31,7 @@ class ShoppingCart {
|
|
|
31
31
|
storage.setPersistedData(identifier, null);
|
|
32
32
|
}
|
|
33
33
|
catch (error) {
|
|
34
|
-
console.
|
|
34
|
+
console.warn(`ShoppingCart clear ${identifier} error`, error);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
/**
|
|
@@ -47,7 +47,7 @@ class ShoppingCart {
|
|
|
47
47
|
return ((_a = storage.getPersistedObject(id)) !== null && _a !== void 0 ? _a : storage.getObject(id));
|
|
48
48
|
}
|
|
49
49
|
catch (error) {
|
|
50
|
-
console.
|
|
50
|
+
console.warn(`ShoppingCart getCartData ${id} error`, error);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
@@ -345,7 +345,7 @@ class ShoppingCart {
|
|
|
345
345
|
}
|
|
346
346
|
}
|
|
347
347
|
catch (error) {
|
|
348
|
-
console.
|
|
348
|
+
console.warn(`ShoppingCart save ${this.identifier} error`, error);
|
|
349
349
|
}
|
|
350
350
|
return data;
|
|
351
351
|
}
|
package/lib/cjs/i18n/en.json
CHANGED
|
@@ -110,6 +110,7 @@
|
|
|
110
110
|
"moreTag": "{0} more",
|
|
111
111
|
"name": "Name",
|
|
112
112
|
"nameB": "Name",
|
|
113
|
+
"networkError": "The local network is faulty and cannot connect to the remote server",
|
|
113
114
|
"newPassword": "New password",
|
|
114
115
|
"newPasswordRequired": "Please enter your new password",
|
|
115
116
|
"newPasswordTip": "New password should be different",
|
package/lib/mjs/app/CoreApp.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { INotifier, NotificationAlign, NotificationCallProps, NotificationContent, NotificationReturn } from '@etsoo/notificationbase';
|
|
2
2
|
import { ApiDataError, IApi, IPData } from '@etsoo/restclient';
|
|
3
|
-
import { DataTypes, DateUtils, IActionResult, IStorage, ListType, ListType1 } from '@etsoo/shared';
|
|
3
|
+
import { DataTypes, DateUtils, ErrorData, IActionResult, IStorage, ListType, ListType1 } from '@etsoo/shared';
|
|
4
4
|
import { AddressRegion } from '../address/AddressRegion';
|
|
5
5
|
import { EntityStatus } from '../business/EntityStatus';
|
|
6
6
|
import { InitCallDto } from '../erp/dto/InitCallDto';
|
|
@@ -189,6 +189,11 @@ export declare abstract class CoreApp<U extends IUser, S extends IAppSettings, N
|
|
|
189
189
|
* @param api Api
|
|
190
190
|
*/
|
|
191
191
|
setApiLoading(api: IApi): void;
|
|
192
|
+
/**
|
|
193
|
+
* Setup frontend logging
|
|
194
|
+
* @param action Custom action
|
|
195
|
+
*/
|
|
196
|
+
setupLogging(action?: (data: ErrorData) => void | Promise<void>): void;
|
|
192
197
|
/**
|
|
193
198
|
* Api init call
|
|
194
199
|
* @param data Data
|
package/lib/mjs/app/CoreApp.js
CHANGED
|
@@ -280,6 +280,7 @@ export class CoreApp {
|
|
|
280
280
|
? api.transformResponse(error.response).status
|
|
281
281
|
: undefined;
|
|
282
282
|
if (status === 401) {
|
|
283
|
+
// Unauthorized
|
|
283
284
|
if (handlerFor401 === false)
|
|
284
285
|
return;
|
|
285
286
|
if (typeof handlerFor401 === 'function') {
|
|
@@ -290,6 +291,17 @@ export class CoreApp {
|
|
|
290
291
|
}
|
|
291
292
|
return;
|
|
292
293
|
}
|
|
294
|
+
else if (error.response == null &&
|
|
295
|
+
(error.message === 'Network Error' ||
|
|
296
|
+
error.message === 'Failed to fetch')) {
|
|
297
|
+
// Network error
|
|
298
|
+
this.notifier.alert(this.get('networkError'));
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
// Log
|
|
303
|
+
console.error('API error', error);
|
|
304
|
+
}
|
|
293
305
|
// Report the error
|
|
294
306
|
this.notifier.alert(this.formatError(error));
|
|
295
307
|
};
|
|
@@ -313,6 +325,23 @@ export class CoreApp {
|
|
|
313
325
|
this.lastCalled = true;
|
|
314
326
|
};
|
|
315
327
|
}
|
|
328
|
+
/**
|
|
329
|
+
* Setup frontend logging
|
|
330
|
+
* @param action Custom action
|
|
331
|
+
*/
|
|
332
|
+
setupLogging(action) {
|
|
333
|
+
action !== null && action !== void 0 ? action : (action = (data) => {
|
|
334
|
+
this.api.post('Auth/LogFrontendError', data, {
|
|
335
|
+
onError: (error) => {
|
|
336
|
+
// Use 'debug' to avoid infinite loop
|
|
337
|
+
console.debug('Log front-end error', data, error);
|
|
338
|
+
// Prevent global error handler
|
|
339
|
+
return false;
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
});
|
|
343
|
+
DomUtils.setupLogging(action);
|
|
344
|
+
}
|
|
316
345
|
/**
|
|
317
346
|
* Api init call
|
|
318
347
|
* @param data Data
|
|
@@ -624,7 +653,7 @@ export class CoreApp {
|
|
|
624
653
|
const iv = enc.Hex.parse(messageEncrypted.substring(34, 66));
|
|
625
654
|
const encrypted = messageEncrypted.substring(66);
|
|
626
655
|
const key = PBKDF2(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, salt, {
|
|
627
|
-
keySize: 8,
|
|
656
|
+
keySize: 8, // 256 / 32
|
|
628
657
|
hasher: algo.SHA256,
|
|
629
658
|
iterations: 1000 * iterations
|
|
630
659
|
});
|
|
@@ -635,7 +664,7 @@ export class CoreApp {
|
|
|
635
664
|
}).toString(enc.Utf8);
|
|
636
665
|
}
|
|
637
666
|
catch (e) {
|
|
638
|
-
console.
|
|
667
|
+
console.error(`CoreApp.decrypt ${messageEncrypted} error`, e);
|
|
639
668
|
return undefined;
|
|
640
669
|
}
|
|
641
670
|
}
|
|
@@ -670,7 +699,7 @@ export class CoreApp {
|
|
|
670
699
|
return this.decrypt(message, passphrase);
|
|
671
700
|
}
|
|
672
701
|
catch (e) {
|
|
673
|
-
console.
|
|
702
|
+
console.error(`CoreApp.decryptEnhanced ${messageEncrypted} error`, e);
|
|
674
703
|
return undefined;
|
|
675
704
|
}
|
|
676
705
|
}
|
|
@@ -750,7 +779,7 @@ export class CoreApp {
|
|
|
750
779
|
const bits = 16; // 128 / 8
|
|
751
780
|
const salt = lib.WordArray.random(bits);
|
|
752
781
|
const key = PBKDF2(passphrase !== null && passphrase !== void 0 ? passphrase : this.passphrase, salt, {
|
|
753
|
-
keySize: 8,
|
|
782
|
+
keySize: 8, // 256 / 32
|
|
754
783
|
hasher: algo.SHA256,
|
|
755
784
|
iterations: 1000 * iterations
|
|
756
785
|
});
|
|
@@ -838,7 +867,7 @@ export class CoreApp {
|
|
|
838
867
|
* @returns Error message
|
|
839
868
|
*/
|
|
840
869
|
formatError(error) {
|
|
841
|
-
return error.
|
|
870
|
+
return `${error.message} (${error.name})`;
|
|
842
871
|
}
|
|
843
872
|
/**
|
|
844
873
|
* Refresh token failed
|
|
@@ -1285,7 +1314,7 @@ export class CoreApp {
|
|
|
1285
1314
|
async signout() {
|
|
1286
1315
|
await this.api.put('User/Signout', { deviceId: this.deviceId }, {
|
|
1287
1316
|
onError: (error) => {
|
|
1288
|
-
console.
|
|
1317
|
+
console.error('CoreApp.signout error', error);
|
|
1289
1318
|
// Prevent further processing
|
|
1290
1319
|
return false;
|
|
1291
1320
|
}
|
package/lib/mjs/app/IApp.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { INotifier, NotificationAlign, NotificationCallProps, NotificationContent, NotificationReturn } from '@etsoo/notificationbase';
|
|
2
2
|
import { ApiDataError, IApi, IPData } from '@etsoo/restclient';
|
|
3
|
-
import { DataTypes, DateUtils, IActionResult, IStorage, ListType, ListType1 } from '@etsoo/shared';
|
|
3
|
+
import { DataTypes, DateUtils, ErrorData, IActionResult, IStorage, ListType, ListType1 } from '@etsoo/shared';
|
|
4
4
|
import { AddressRegion } from '../address/AddressRegion';
|
|
5
5
|
import { IUser } from '../state/User';
|
|
6
6
|
import { IAppSettings } from './AppSettings';
|
|
@@ -459,6 +459,11 @@ export interface IApp {
|
|
|
459
459
|
* @param api Api
|
|
460
460
|
*/
|
|
461
461
|
setApiLoading(api: IApi): void;
|
|
462
|
+
/**
|
|
463
|
+
* Setup frontend logging
|
|
464
|
+
* @param action Custom action
|
|
465
|
+
*/
|
|
466
|
+
setupLogging(action?: (data: ErrorData) => void | Promise<void>): void;
|
|
462
467
|
/**
|
|
463
468
|
* Signout, with userLogout and toLoginPage
|
|
464
469
|
*/
|
|
@@ -28,7 +28,7 @@ export class ShoppingCart {
|
|
|
28
28
|
storage.setPersistedData(identifier, null);
|
|
29
29
|
}
|
|
30
30
|
catch (error) {
|
|
31
|
-
console.
|
|
31
|
+
console.warn(`ShoppingCart clear ${identifier} error`, error);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
@@ -44,7 +44,7 @@ export class ShoppingCart {
|
|
|
44
44
|
return ((_a = storage.getPersistedObject(id)) !== null && _a !== void 0 ? _a : storage.getObject(id));
|
|
45
45
|
}
|
|
46
46
|
catch (error) {
|
|
47
|
-
console.
|
|
47
|
+
console.warn(`ShoppingCart getCartData ${id} error`, error);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
@@ -342,7 +342,7 @@ export class ShoppingCart {
|
|
|
342
342
|
}
|
|
343
343
|
}
|
|
344
344
|
catch (error) {
|
|
345
|
-
console.
|
|
345
|
+
console.warn(`ShoppingCart save ${this.identifier} error`, error);
|
|
346
346
|
}
|
|
347
347
|
return data;
|
|
348
348
|
}
|
package/lib/mjs/i18n/en.json
CHANGED
|
@@ -110,6 +110,7 @@
|
|
|
110
110
|
"moreTag": "{0} more",
|
|
111
111
|
"name": "Name",
|
|
112
112
|
"nameB": "Name",
|
|
113
|
+
"networkError": "The local network is faulty and cannot connect to the remote server",
|
|
113
114
|
"newPassword": "New password",
|
|
114
115
|
"newPasswordRequired": "Please enter your new password",
|
|
115
116
|
"newPasswordTip": "New password should be different",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@etsoo/appscript",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.75",
|
|
4
4
|
"description": "Applications shared TypeScript framework",
|
|
5
5
|
"main": "lib/cjs/index.js",
|
|
6
6
|
"module": "lib/mjs/index.js",
|
|
@@ -52,22 +52,22 @@
|
|
|
52
52
|
},
|
|
53
53
|
"homepage": "https://github.com/ETSOO/AppScript#readme",
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@etsoo/notificationbase": "^1.1.
|
|
56
|
-
"@etsoo/restclient": "^1.0.
|
|
57
|
-
"@etsoo/shared": "^1.2.
|
|
55
|
+
"@etsoo/notificationbase": "^1.1.35",
|
|
56
|
+
"@etsoo/restclient": "^1.0.98",
|
|
57
|
+
"@etsoo/shared": "^1.2.26",
|
|
58
58
|
"crypto-js": "^4.2.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@babel/cli": "^7.23.
|
|
62
|
-
"@babel/core": "^7.23.
|
|
63
|
-
"@babel/plugin-transform-runtime": "^7.23.
|
|
64
|
-
"@babel/preset-env": "^7.23.
|
|
65
|
-
"@babel/runtime-corejs3": "^7.23.
|
|
66
|
-
"@types/crypto-js": "^4.2.
|
|
67
|
-
"@types/jest": "^29.5.
|
|
61
|
+
"@babel/cli": "^7.23.9",
|
|
62
|
+
"@babel/core": "^7.23.9",
|
|
63
|
+
"@babel/plugin-transform-runtime": "^7.23.9",
|
|
64
|
+
"@babel/preset-env": "^7.23.9",
|
|
65
|
+
"@babel/runtime-corejs3": "^7.23.9",
|
|
66
|
+
"@types/crypto-js": "^4.2.2",
|
|
67
|
+
"@types/jest": "^29.5.12",
|
|
68
68
|
"jest": "^29.7.0",
|
|
69
69
|
"jest-environment-jsdom": "^29.7.0",
|
|
70
|
-
"ts-jest": "^29.1.
|
|
71
|
-
"typescript": "^5.
|
|
70
|
+
"ts-jest": "^29.1.2",
|
|
71
|
+
"typescript": "^5.3.3"
|
|
72
72
|
}
|
|
73
73
|
}
|
package/src/app/CoreApp.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
DataTypes,
|
|
13
13
|
DateUtils,
|
|
14
14
|
DomUtils,
|
|
15
|
+
ErrorData,
|
|
15
16
|
IActionResult,
|
|
16
17
|
IStorage,
|
|
17
18
|
ListType,
|
|
@@ -469,6 +470,7 @@ export abstract class CoreApp<
|
|
|
469
470
|
: undefined;
|
|
470
471
|
|
|
471
472
|
if (status === 401) {
|
|
473
|
+
// Unauthorized
|
|
472
474
|
if (handlerFor401 === false) return;
|
|
473
475
|
if (typeof handlerFor401 === 'function') {
|
|
474
476
|
handlerFor401();
|
|
@@ -476,6 +478,17 @@ export abstract class CoreApp<
|
|
|
476
478
|
this.tryLogin();
|
|
477
479
|
}
|
|
478
480
|
return;
|
|
481
|
+
} else if (
|
|
482
|
+
error.response == null &&
|
|
483
|
+
(error.message === 'Network Error' ||
|
|
484
|
+
error.message === 'Failed to fetch')
|
|
485
|
+
) {
|
|
486
|
+
// Network error
|
|
487
|
+
this.notifier.alert(this.get('networkError')!);
|
|
488
|
+
return;
|
|
489
|
+
} else {
|
|
490
|
+
// Log
|
|
491
|
+
console.error('API error', error);
|
|
479
492
|
}
|
|
480
493
|
|
|
481
494
|
// Report the error
|
|
@@ -504,6 +517,25 @@ export abstract class CoreApp<
|
|
|
504
517
|
};
|
|
505
518
|
}
|
|
506
519
|
|
|
520
|
+
/**
|
|
521
|
+
* Setup frontend logging
|
|
522
|
+
* @param action Custom action
|
|
523
|
+
*/
|
|
524
|
+
public setupLogging(action?: (data: ErrorData) => void | Promise<void>) {
|
|
525
|
+
action ??= (data) => {
|
|
526
|
+
this.api.post('Auth/LogFrontendError', data, {
|
|
527
|
+
onError: (error) => {
|
|
528
|
+
// Use 'debug' to avoid infinite loop
|
|
529
|
+
console.debug('Log front-end error', data, error);
|
|
530
|
+
|
|
531
|
+
// Prevent global error handler
|
|
532
|
+
return false;
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
};
|
|
536
|
+
DomUtils.setupLogging(action);
|
|
537
|
+
}
|
|
538
|
+
|
|
507
539
|
/**
|
|
508
540
|
* Api init call
|
|
509
541
|
* @param data Data
|
|
@@ -905,7 +937,7 @@ export abstract class CoreApp<
|
|
|
905
937
|
mode: mode.CBC
|
|
906
938
|
}).toString(enc.Utf8);
|
|
907
939
|
} catch (e) {
|
|
908
|
-
console.
|
|
940
|
+
console.error(`CoreApp.decrypt ${messageEncrypted} error`, e);
|
|
909
941
|
return undefined;
|
|
910
942
|
}
|
|
911
943
|
}
|
|
@@ -952,7 +984,10 @@ export abstract class CoreApp<
|
|
|
952
984
|
|
|
953
985
|
return this.decrypt(message, passphrase);
|
|
954
986
|
} catch (e) {
|
|
955
|
-
console.
|
|
987
|
+
console.error(
|
|
988
|
+
`CoreApp.decryptEnhanced ${messageEncrypted} error`,
|
|
989
|
+
e
|
|
990
|
+
);
|
|
956
991
|
return undefined;
|
|
957
992
|
}
|
|
958
993
|
}
|
|
@@ -1175,7 +1210,7 @@ export abstract class CoreApp<
|
|
|
1175
1210
|
* @returns Error message
|
|
1176
1211
|
*/
|
|
1177
1212
|
formatError(error: ApiDataError) {
|
|
1178
|
-
return error.
|
|
1213
|
+
return `${error.message} (${error.name})`;
|
|
1179
1214
|
}
|
|
1180
1215
|
|
|
1181
1216
|
/**
|
|
@@ -1686,7 +1721,7 @@ export abstract class CoreApp<
|
|
|
1686
1721
|
{ deviceId: this.deviceId },
|
|
1687
1722
|
{
|
|
1688
1723
|
onError: (error) => {
|
|
1689
|
-
console.
|
|
1724
|
+
console.error('CoreApp.signout error', error);
|
|
1690
1725
|
// Prevent further processing
|
|
1691
1726
|
return false;
|
|
1692
1727
|
}
|
package/src/app/IApp.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { ApiDataError, IApi, IPData } from '@etsoo/restclient';
|
|
|
9
9
|
import {
|
|
10
10
|
DataTypes,
|
|
11
11
|
DateUtils,
|
|
12
|
+
ErrorData,
|
|
12
13
|
IActionResult,
|
|
13
14
|
IStorage,
|
|
14
15
|
ListType,
|
|
@@ -623,6 +624,12 @@ export interface IApp {
|
|
|
623
624
|
*/
|
|
624
625
|
setApiLoading(api: IApi): void;
|
|
625
626
|
|
|
627
|
+
/**
|
|
628
|
+
* Setup frontend logging
|
|
629
|
+
* @param action Custom action
|
|
630
|
+
*/
|
|
631
|
+
setupLogging(action?: (data: ErrorData) => void | Promise<void>): void;
|
|
632
|
+
|
|
626
633
|
/**
|
|
627
634
|
* Signout, with userLogout and toLoginPage
|
|
628
635
|
*/
|
|
@@ -166,7 +166,7 @@ export class ShoppingCart<T extends ShoppingCartItem> {
|
|
|
166
166
|
storage.setData(identifier, null);
|
|
167
167
|
storage.setPersistedData(identifier, null);
|
|
168
168
|
} catch (error) {
|
|
169
|
-
console.
|
|
169
|
+
console.warn(`ShoppingCart clear ${identifier} error`, error);
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
|
|
@@ -187,7 +187,7 @@ export class ShoppingCart<T extends ShoppingCartItem> {
|
|
|
187
187
|
storage.getObject<ShoppingCartData<D>>(id)
|
|
188
188
|
);
|
|
189
189
|
} catch (error) {
|
|
190
|
-
console.
|
|
190
|
+
console.warn(`ShoppingCart getCartData ${id} error`, error);
|
|
191
191
|
}
|
|
192
192
|
}
|
|
193
193
|
|
|
@@ -582,7 +582,7 @@ export class ShoppingCart<T extends ShoppingCartItem> {
|
|
|
582
582
|
this.storage.setData(this.identifier, data);
|
|
583
583
|
}
|
|
584
584
|
} catch (error) {
|
|
585
|
-
console.
|
|
585
|
+
console.warn(`ShoppingCart save ${this.identifier} error`, error);
|
|
586
586
|
}
|
|
587
587
|
|
|
588
588
|
return data;
|
package/src/i18n/en.json
CHANGED
|
@@ -110,6 +110,7 @@
|
|
|
110
110
|
"moreTag": "{0} more",
|
|
111
111
|
"name": "Name",
|
|
112
112
|
"nameB": "Name",
|
|
113
|
+
"networkError": "The local network is faulty and cannot connect to the remote server",
|
|
113
114
|
"newPassword": "New password",
|
|
114
115
|
"newPasswordRequired": "Please enter your new password",
|
|
115
116
|
"newPasswordTip": "New password should be different",
|
package/src/i18n/zh-Hans.json
CHANGED