oak-backend-base 4.1.22 → 4.1.24
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/AppLoader.d.ts +14 -3
- package/lib/AppLoader.js +56 -4
- package/lib/Synchronizer.d.ts +1 -1
- package/lib/Synchronizer.js +1 -1
- package/lib/cluster/env.js +1 -2
- package/lib/routines/i18n.js +2 -3
- package/lib/types/index.d.ts +9 -0
- package/lib/types/index.js +2 -0
- package/lib/utils/requirePrj.js +1 -1
- package/package.json +3 -3
package/lib/AppLoader.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
1
|
import { EntityDict as BaseEntityDict } from 'oak-domain/lib/base-app-domain';
|
|
3
2
|
import { AppLoader as GeneralAppLoader, Trigger, EntityDict, Watcher, OpRecord, FreeTimer, OperationResult } from "oak-domain/lib/types";
|
|
4
3
|
import { DbStore } from "./DbStore";
|
|
@@ -8,6 +7,7 @@ import { Namespace } from 'socket.io';
|
|
|
8
7
|
import DataSubscriber from './cluster/DataSubscriber';
|
|
9
8
|
import Synchronizer from './Synchronizer';
|
|
10
9
|
import { AsyncContext } from 'oak-domain/lib/store/AsyncRowStore';
|
|
10
|
+
import { InternalErrorHandler } from './types';
|
|
11
11
|
export declare class AppLoader<ED extends EntityDict & BaseEntityDict, Cxt extends BackendRuntimeContext<ED>> extends GeneralAppLoader<ED, Cxt> {
|
|
12
12
|
protected dbStore: DbStore<ED, Cxt>;
|
|
13
13
|
private aspectDict;
|
|
@@ -18,6 +18,17 @@ export declare class AppLoader<ED extends EntityDict & BaseEntityDict, Cxt exten
|
|
|
18
18
|
private nsSocket?;
|
|
19
19
|
private watcherTimerId?;
|
|
20
20
|
private scheduledJobs;
|
|
21
|
+
private internalErrorHandlers;
|
|
22
|
+
regAllExceptionHandler(): void;
|
|
23
|
+
/**
|
|
24
|
+
* 注册一个内部错误处理器
|
|
25
|
+
* @param handler 内部错误处理器
|
|
26
|
+
*/
|
|
27
|
+
registerInternalErrorHandler(handler: InternalErrorHandler<ED, Cxt>): void;
|
|
28
|
+
/**
|
|
29
|
+
* 发布内部错误事件给注册的处理器
|
|
30
|
+
*/
|
|
31
|
+
private publishInternalError;
|
|
21
32
|
private requireSth;
|
|
22
33
|
protected makeContext(cxtStr?: string, headers?: IncomingHttpHeaders): Promise<Cxt>;
|
|
23
34
|
/**
|
|
@@ -38,9 +49,9 @@ export declare class AppLoader<ED extends EntityDict & BaseEntityDict, Cxt exten
|
|
|
38
49
|
initialize(ifExists?: 'drop' | 'omit' | 'dropIfNotStatic'): Promise<void>;
|
|
39
50
|
getStore(): DbStore<ED, Cxt>;
|
|
40
51
|
getEndpoints(prefix: string): [string, "post" | "get" | "put" | "delete", string, (params: Record<string, string>, headers: IncomingHttpHeaders, req: IncomingMessage, body?: any) => Promise<{
|
|
41
|
-
headers?: Record<string, string | string[]
|
|
52
|
+
headers?: Record<string, string | string[]>;
|
|
42
53
|
data: any;
|
|
43
|
-
statusCode?: number
|
|
54
|
+
statusCode?: number;
|
|
44
55
|
}>][];
|
|
45
56
|
protected operateInWatcher<T extends keyof ED>(entity: T, operation: ED[T]['Update'], context: Cxt, singleton?: true): Promise<OperationResult<ED>>;
|
|
46
57
|
protected selectInWatcher<T extends keyof ED>(entity: T, selection: ED[T]['Selection'], context: Cxt, forUpdate?: true, singleton?: true): Promise<Partial<ED[T]["Schema"]>[]>;
|
package/lib/AppLoader.js
CHANGED
|
@@ -28,6 +28,51 @@ class AppLoader extends types_1.AppLoader {
|
|
|
28
28
|
nsSocket;
|
|
29
29
|
watcherTimerId;
|
|
30
30
|
scheduledJobs = {};
|
|
31
|
+
internalErrorHandlers = new Array();
|
|
32
|
+
regAllExceptionHandler() {
|
|
33
|
+
const handlers = this.requireSth('lib/configuration/exception');
|
|
34
|
+
if (Array.isArray(handlers)) {
|
|
35
|
+
handlers.forEach((handler) => {
|
|
36
|
+
console.log(`注册内部错误处理器: ${handler.name}`);
|
|
37
|
+
this.registerInternalErrorHandler(handler);
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
console.warn('lib/configuration/exception必须默认导出一个处理器数组,当前导出类型不正确,将忽略此配置');
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* 注册一个内部错误处理器
|
|
46
|
+
* @param handler 内部错误处理器
|
|
47
|
+
*/
|
|
48
|
+
registerInternalErrorHandler(handler) {
|
|
49
|
+
// 检查有没有名称重复
|
|
50
|
+
if (this.internalErrorHandlers.find(h => h.name === handler.name)) {
|
|
51
|
+
throw new Error(`内部错误处理器名称重复: ${handler.name}`);
|
|
52
|
+
}
|
|
53
|
+
this.internalErrorHandlers.push(handler);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 发布内部错误事件给注册的处理器
|
|
57
|
+
*/
|
|
58
|
+
async publishInternalError(type, message, err) {
|
|
59
|
+
const errorToPublish = (0, lodash_1.cloneDeep)(err);
|
|
60
|
+
await Promise.all(this.internalErrorHandlers.map((handler) => {
|
|
61
|
+
return new Promise(async (resolve) => {
|
|
62
|
+
try {
|
|
63
|
+
const ctx = await this.makeContext();
|
|
64
|
+
console.log(`调用internalErrorHandler【${handler.name}】处理内部错误事件`);
|
|
65
|
+
handler.handle(ctx, type, message, errorToPublish);
|
|
66
|
+
}
|
|
67
|
+
catch (e) {
|
|
68
|
+
console.error('执行internalErrorHandler时出错', e);
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
resolve();
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
31
76
|
requireSth(filePath) {
|
|
32
77
|
return (0, requirePrj_1.default)(this.path, filePath, this.externalDependencies);
|
|
33
78
|
}
|
|
@@ -172,7 +217,9 @@ class AppLoader extends types_1.AppLoader {
|
|
|
172
217
|
};
|
|
173
218
|
}
|
|
174
219
|
catch (err) {
|
|
220
|
+
console.error(`执行aspect「${name}」出错`, err);
|
|
175
221
|
await context.rollback();
|
|
222
|
+
this.publishInternalError(`aspect`, `执行aspect「${name}」出错`, err);
|
|
176
223
|
if (err instanceof types_1.OakException) {
|
|
177
224
|
throw err;
|
|
178
225
|
}
|
|
@@ -357,6 +404,7 @@ class AppLoader extends types_1.AppLoader {
|
|
|
357
404
|
else {
|
|
358
405
|
await context.rollback();
|
|
359
406
|
}
|
|
407
|
+
// 不能在这里publish,因为这个方法可能是在timer中调用,也可能是在routine中调用
|
|
360
408
|
throw err;
|
|
361
409
|
}
|
|
362
410
|
}
|
|
@@ -382,6 +430,7 @@ class AppLoader extends types_1.AppLoader {
|
|
|
382
430
|
}
|
|
383
431
|
catch (err) {
|
|
384
432
|
console.error(`执行watcher【${watcher.name}】失败,耗时【${Date.now() - start}】,结果是:`, err);
|
|
433
|
+
await this.publishInternalError(`watcher`, `执行watcher【${watcher.name}】失败`, err);
|
|
385
434
|
}
|
|
386
435
|
};
|
|
387
436
|
const doWatchers = async () => {
|
|
@@ -400,6 +449,7 @@ class AppLoader extends types_1.AppLoader {
|
|
|
400
449
|
}
|
|
401
450
|
catch (err) {
|
|
402
451
|
console.error(`执行了checkpoint,发生错误:`, err);
|
|
452
|
+
await this.publishInternalError(`checkpoint`, `执行checkpoint发生错误`, err);
|
|
403
453
|
}
|
|
404
454
|
this.watcherTimerId = setTimeout(() => doWatchers(), 120000);
|
|
405
455
|
};
|
|
@@ -423,7 +473,8 @@ class AppLoader extends types_1.AppLoader {
|
|
|
423
473
|
console.log(`定时器【${name}】执行成功,耗时${Date.now() - start}毫秒】,结果是`, result);
|
|
424
474
|
}
|
|
425
475
|
catch (err) {
|
|
426
|
-
console.
|
|
476
|
+
console.error(`定时器【${name}】执行失败,耗时${Date.now() - start}毫秒】,错误是`, err);
|
|
477
|
+
this.publishInternalError(`timer`, `定时器【${name}】执行失败`, err);
|
|
427
478
|
}
|
|
428
479
|
}
|
|
429
480
|
else {
|
|
@@ -436,13 +487,14 @@ class AppLoader extends types_1.AppLoader {
|
|
|
436
487
|
await context.commit();
|
|
437
488
|
}
|
|
438
489
|
catch (err) {
|
|
439
|
-
console.
|
|
490
|
+
console.error(`定时器【${name}】执行失败,耗时${Date.now() - start}毫秒,错误是`, err);
|
|
440
491
|
if (err instanceof types_1.OakPartialSuccess) {
|
|
441
492
|
await context.commit();
|
|
442
493
|
}
|
|
443
494
|
else {
|
|
444
495
|
await context.rollback();
|
|
445
496
|
}
|
|
497
|
+
this.publishInternalError(`timer`, `定时器【${name}】执行失败`, err);
|
|
446
498
|
}
|
|
447
499
|
}
|
|
448
500
|
});
|
|
@@ -468,7 +520,7 @@ class AppLoader extends types_1.AppLoader {
|
|
|
468
520
|
console.log(`例程【${routine.name}】执行成功,耗时${Date.now() - start}毫秒,结果是`, result);
|
|
469
521
|
}
|
|
470
522
|
catch (err) {
|
|
471
|
-
console.
|
|
523
|
+
console.error(`例程【${routine.name}】执行失败,耗时${Date.now() - start}毫秒,错误是`, err);
|
|
472
524
|
throw err;
|
|
473
525
|
}
|
|
474
526
|
}
|
|
@@ -484,7 +536,7 @@ class AppLoader extends types_1.AppLoader {
|
|
|
484
536
|
await context.commit();
|
|
485
537
|
}
|
|
486
538
|
catch (err) {
|
|
487
|
-
console.
|
|
539
|
+
console.error(`例程【${name}】执行失败,耗时${Date.now() - start}毫秒,错误是`, err);
|
|
488
540
|
await context.rollback();
|
|
489
541
|
throw err;
|
|
490
542
|
}
|
package/lib/Synchronizer.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export default class Synchronizer<ED extends EntityDict & BaseEntityDict, Cxt ex
|
|
|
27
27
|
* 根据sync的定义,生成对应的 commit triggers
|
|
28
28
|
* @returns
|
|
29
29
|
*/
|
|
30
|
-
getSyncTriggers(): VolatileTrigger<ED, keyof ED, Cxt
|
|
30
|
+
getSyncTriggers(): Array<VolatileTrigger<ED, keyof ED, Cxt>>;
|
|
31
31
|
getSelfEndpoint(): EndpointItem<ED, Cxt>;
|
|
32
32
|
tryCreateSyncProcess(): void;
|
|
33
33
|
}
|
package/lib/Synchronizer.js
CHANGED
|
@@ -114,7 +114,7 @@ class Synchronizer {
|
|
|
114
114
|
remoteEntityId: entityId,
|
|
115
115
|
data: queue.map((ele) => ({
|
|
116
116
|
entity: ele.oper.targetEntity,
|
|
117
|
-
rowIds: ele.oper.filter.id.$in,
|
|
117
|
+
rowIds: ele.oper.filter.id.$in, // 暂时应该没什么用
|
|
118
118
|
action: ele.oper.action,
|
|
119
119
|
data: ele.oper.data,
|
|
120
120
|
})),
|
package/lib/cluster/env.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getClusterInfo =
|
|
3
|
+
exports.getClusterInfo = getClusterInfo;
|
|
4
4
|
function getProcessEnvOption(option) {
|
|
5
5
|
if (process.env.hasOwnProperty(option)) {
|
|
6
6
|
return process.env[option];
|
|
@@ -54,4 +54,3 @@ const MyClusterInfo = initialize();
|
|
|
54
54
|
function getClusterInfo() {
|
|
55
55
|
return MyClusterInfo;
|
|
56
56
|
}
|
|
57
|
-
exports.getClusterInfo = getClusterInfo;
|
package/lib/routines/i18n.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.checkI18n = checkI18n;
|
|
4
|
+
exports.checkAndUpdateI18n = checkAndUpdateI18n;
|
|
4
5
|
const tslib_1 = require("tslib");
|
|
5
6
|
const node_path_1 = require("node:path");
|
|
6
7
|
const requirePrj_1 = tslib_1.__importDefault(require("../utils/requirePrj"));
|
|
@@ -66,7 +67,6 @@ async function checkAndUpdateI18nInner(context, onlyCheck) {
|
|
|
66
67
|
function checkI18n(context) {
|
|
67
68
|
return checkAndUpdateI18nInner(context, true);
|
|
68
69
|
}
|
|
69
|
-
exports.checkI18n = checkI18n;
|
|
70
70
|
/**
|
|
71
71
|
* 检查项目目录下的i18n数据和数据库中的差异,并更新
|
|
72
72
|
* @param context
|
|
@@ -75,4 +75,3 @@ exports.checkI18n = checkI18n;
|
|
|
75
75
|
function checkAndUpdateI18n(context) {
|
|
76
76
|
return checkAndUpdateI18nInner(context);
|
|
77
77
|
}
|
|
78
|
-
exports.checkAndUpdateI18n = checkAndUpdateI18n;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { BaseEntityDict } from "oak-domain";
|
|
2
|
+
import { AsyncContext } from "oak-domain/lib/store/AsyncRowStore";
|
|
3
|
+
import { EntityDict } from "oak-domain/lib/types";
|
|
4
|
+
export type InternalErrorType = 'aspect' | 'trigger' | 'watcher' | 'timer' | 'checkpoint';
|
|
5
|
+
export type InternalErrorHandler<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>> = {
|
|
6
|
+
name: string;
|
|
7
|
+
handle: (ctx: Cxt, type: InternalErrorType, message: string, err: Error) => Promise<void>;
|
|
8
|
+
};
|
|
9
|
+
export type ExceptionPublisher = (type: string, message: string, err: any) => Promise<void>;
|
package/lib/utils/requirePrj.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = requireSth;
|
|
3
4
|
const fs_1 = require("fs");
|
|
4
5
|
const lodash_1 = require("oak-domain/lib/utils/lodash");
|
|
5
6
|
const path_1 = require("path");
|
|
@@ -20,4 +21,3 @@ function requireSth(prjPath, filePath, dependencies) {
|
|
|
20
21
|
}
|
|
21
22
|
return (0, lodash_1.mergeConcatMany)(sthExternal);
|
|
22
23
|
}
|
|
23
|
-
exports.default = requireSth;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oak-backend-base",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.24",
|
|
4
4
|
"description": "oak-backend-base",
|
|
5
5
|
"main": "lib/index",
|
|
6
6
|
"author": {
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"node-schedule": "^2.1.0",
|
|
24
24
|
"oak-common-aspect": "^3.0.5",
|
|
25
25
|
"oak-db": "^3.3.11",
|
|
26
|
-
"oak-domain": "^5.1.
|
|
27
|
-
"oak-frontend-base": "^5.3.
|
|
26
|
+
"oak-domain": "^5.1.30",
|
|
27
|
+
"oak-frontend-base": "^5.3.43",
|
|
28
28
|
"socket.io": "^4.8.1",
|
|
29
29
|
"socket.io-client": "^4.7.2",
|
|
30
30
|
"uuid": "^8.3.2"
|