mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: server: allow execution flow control
This commit is contained in:
1 parent
594e97194b
commit
b9bc504917
1 file changed
+33
-23
@@ -256,6 +256,7 @@ export class Handler extends HandlerCommon {
|
|||||||
async function bail(name: string, ...args: any[]) {
|
async function bail(name: string, ...args: any[]) {
|
||||||
const r = await bus.bail(name, ...args);
|
const r = await bus.bail(name, ...args);
|
||||||
if (r instanceof Error) throw r;
|
if (r instanceof Error) throw r;
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handle(ctx: KoaContext, HandlerClass, checker) {
|
async function handle(ctx: KoaContext, HandlerClass, checker) {
|
||||||
@@ -287,29 +288,38 @@ async function handle(ctx: KoaContext, HandlerClass, checker) {
|
|||||||
throw new MethodNotAllowedError(method);
|
throw new MethodNotAllowedError(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
await h.init();
|
const name = HandlerClass.name.replace(/Handler$/, '');
|
||||||
await bail('handler/init', h);
|
const steps = [
|
||||||
await bail(`handler/before-prepare/${HandlerClass.name.replace(/Handler$/, '')}`, h);
|
'init', 'handler/init', `handler/before-prepare/${name}`, 'handler/before-prepare',
|
||||||
await bail('handler/before-prepare', h);
|
'log/__prepare', '__prepare', '_prepare', 'prepare',
|
||||||
h.args.__prepare = Date.now();
|
'log/__prepareDone', `handler/before/${name}`, 'handler/before',
|
||||||
if (h.__prepare) await h.__prepare(args);
|
'log/__method', 'all', method, 'log/__methodDone',
|
||||||
if (h._prepare) await h._prepare(args);
|
...operation ? [
|
||||||
if (h.prepare) await h.prepare(args);
|
`handler/before-operation/${name}`, 'handler/before-operation',
|
||||||
h.args.__prepareDone = Date.now();
|
`post${operation}`, 'log/__operationDone',
|
||||||
await bail(`handler/before/${HandlerClass.name.replace(/Handler$/, '')}`, h);
|
] : [],
|
||||||
await bail('handler/before', h);
|
`handler/after/${name}`, 'handler/after', 'cleanup',
|
||||||
h.args.__method = Date.now();
|
`handler/finish/${name}`, 'handler/finish',
|
||||||
if (h.all) await h.all(args);
|
];
|
||||||
if (h[method]) await h[method](args);
|
|
||||||
h.args.__methodDone = Date.now();
|
let current = 0;
|
||||||
await bail(`handler/before-operation/${HandlerClass.name.replace(/Handler$/, '')}`, h);
|
while (current < steps.length) {
|
||||||
await bail('handler/before-operation', h);
|
const step = steps[current];
|
||||||
if (operation) await h[`post${operation}`](args);
|
let control;
|
||||||
await bail(`handler/after/${HandlerClass.name.replace(/Handler$/, '')}`, h);
|
if (step.startsWith('log/')) h.args[step.slice(4)] = Date.now();
|
||||||
await bail('handler/after', h);
|
// eslint-disable-next-line no-await-in-loop
|
||||||
if (h.cleanup) await h.cleanup(args);
|
else if (step.startsWith('handler/')) control = await bail(step, h);
|
||||||
await bail(`handler/finish/${HandlerClass.name.replace(/Handler$/, '')}`, h);
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await bail('handler/finish', h);
|
else if (typeof h[step] === 'function') control = await h[step](args);
|
||||||
|
if (control) {
|
||||||
|
const index = steps.findIndex((i) => control === i);
|
||||||
|
if (index === -1) throw new Error(`Invalid control: ${control}`);
|
||||||
|
if (index <= current) {
|
||||||
|
logger.warn('Returning to previous step is not recommended:', step, '->', control);
|
||||||
|
}
|
||||||
|
current = index;
|
||||||
|
} else current++;
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
try {
|
try {
|
||||||
await bail(`handler/error/${HandlerClass.name.replace(/Handler$/, '')}`, h, e);
|
await bail(`handler/error/${HandlerClass.name.replace(/Handler$/, '')}`, h, e);
|
||||||
|
|||||||
Reference in new issue
Block a user