Skip to content

Commit 9dd81af

Browse files
committed
feat: rework error hooks
1 parent 7bf2745 commit 9dd81af

1 file changed

Lines changed: 40 additions & 26 deletions

File tree

packages/repack/src/modules/ScriptManager/ScriptManager.ts

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
// biome-ignore lint/style/useNodejsImportProtocol: use 'events' module instead of node builtin
22
import EventEmitter from 'events';
3-
import {
4-
AsyncSeriesBailHook,
5-
AsyncSeriesHook,
6-
AsyncSeriesWaterfallHook,
7-
} from 'tapable';
3+
import { AsyncSeriesBailHook, AsyncSeriesWaterfallHook } from 'tapable';
84
import NativeScriptManager, {
95
type NormalizedScriptLocator,
106
} from './NativeScriptManager.js';
@@ -224,17 +220,20 @@ export class ScriptManager extends EventEmitter {
224220
AfterResolveHookOptions,
225221
AfterResolveHookOptions
226222
>(['args']),
227-
errorResolve: new AsyncSeriesHook<ErrorResolveHookOptions, void>(['args']),
223+
errorResolve: new AsyncSeriesBailHook<
224+
ErrorResolveHookOptions,
225+
ScriptLocator | undefined
226+
>(['args']),
228227
beforeLoad: new AsyncSeriesWaterfallHook<
229228
BeforeLoadHookOptions,
230229
BeforeLoadHookOptions
231230
>(['args']),
232-
load: new AsyncSeriesBailHook<LoadHookOptions, void>(['args']),
231+
load: new AsyncSeriesBailHook<LoadHookOptions, boolean>(['args']),
233232
afterLoad: new AsyncSeriesWaterfallHook<
234233
AfterLoadHookOptions,
235234
AfterLoadHookOptions
236235
>(['args']),
237-
errorLoad: new AsyncSeriesHook<ErrorLoadHookOptions, void>(['args']),
236+
errorLoad: new AsyncSeriesBailHook<ErrorLoadHookOptions, boolean>(['args']),
238237
};
239238

240239
public hooks = {
@@ -380,6 +379,8 @@ export class ScriptManager extends EventEmitter {
380379
webpackContext: _webpackContext,
381380
};
382381

382+
let locator: ScriptLocator | undefined;
383+
383384
try {
384385
await this.initCache();
385386

@@ -398,8 +399,6 @@ export class ScriptManager extends EventEmitter {
398399
caller: options.caller,
399400
});
400401

401-
let locator: ScriptLocator | undefined;
402-
403402
if (this.hookMap.resolve.isUsed()) {
404403
// obtain the result from custom implementation through the resolve hook
405404
locator = await this.hookMap.resolve.promise({
@@ -437,7 +436,22 @@ export class ScriptManager extends EventEmitter {
437436
if (typeof locator.url === 'function') {
438437
locator.url = locator.url(options.webpackContext);
439438
}
439+
} catch (error) {
440+
locator = await this.hookMap.errorResolve.promise({
441+
options,
442+
error: error as Error,
443+
});
444+
445+
if (!locator) {
446+
this.handleError(
447+
error,
448+
'[ScriptManager] Failed while resolving script locator:',
449+
{ scriptId: options.scriptId, caller: options.caller }
450+
);
451+
}
452+
}
440453

454+
try {
441455
const script = await this.createScript(
442456
options.scriptId,
443457
options.caller,
@@ -446,15 +460,10 @@ export class ScriptManager extends EventEmitter {
446460
this.emit('resolved', script.toObject());
447461
return script;
448462
} catch (error) {
449-
await this.hookMap.errorResolve.promise({
450-
options,
451-
error: error as Error,
463+
this.handleError(error, '[ScriptManager] Failed while creating script:', {
464+
scriptId: options.scriptId,
465+
caller: options.caller,
452466
});
453-
this.handleError(
454-
error,
455-
'[ScriptManager] Failed while resolving script locator:',
456-
{ scriptId: options.scriptId, caller: options.caller }
457-
);
458467
}
459468
}
460469

@@ -532,6 +541,8 @@ export class ScriptManager extends EventEmitter {
532541
webpackContext: _webpackContext,
533542
};
534543

544+
let loaded = false;
545+
535546
const uniqueId = Script.getScriptUniqueId(options.scriptId, options.caller);
536547

537548
if (this.scriptsPromises[uniqueId]) {
@@ -564,7 +575,7 @@ export class ScriptManager extends EventEmitter {
564575
this.emit('loading', script.toObject());
565576

566577
if (this.hookMap.load.isUsed()) {
567-
await this.hookMap.load.promise({
578+
loaded = await this.hookMap.load.promise({
568579
options,
569580
script,
570581
loadScript: async (
@@ -576,6 +587,7 @@ export class ScriptManager extends EventEmitter {
576587
});
577588
} else {
578589
await this.loadScriptWithRetry(options.scriptId, script.locator);
590+
loaded = true;
579591
}
580592

581593
if (this.hookMap.afterLoad.isUsed()) {
@@ -589,16 +601,18 @@ export class ScriptManager extends EventEmitter {
589601
await this.updateCache(script);
590602
} catch (error) {
591603
const { code } = error as Error & { code: string };
592-
await this.hookMap.errorLoad.promise({
604+
loaded = await this.hookMap.errorLoad.promise({
593605
options,
594606
error: error as Error,
595607
});
596-
this.handleError(
597-
error,
598-
'[ScriptManager] Failed to load script:',
599-
code ? `[${code}]` : '',
600-
script.toObject()
601-
);
608+
if (!loaded) {
609+
this.handleError(
610+
error,
611+
'[ScriptManager] Failed to load script:',
612+
code ? `[${code}]` : '',
613+
script.toObject()
614+
);
615+
}
602616
} finally {
603617
// should delete script promise even script failed
604618
delete this.scriptsPromises[uniqueId];

0 commit comments

Comments
 (0)