Skip to content

Commit 5707578

Browse files
committed
refactor(@angular-devkit/build-angular): properly display errors originating in ESM loader hooks
Currently, errors occurring in ESM loader hooks while using `--import` are not correctly displayed, as they cannot be transferred from the worker to the main thread. Although the error is an instance of Error, it contains non-transferable properties and cannot be transmitted from a worker when --import is used. Consequently, when read outside of the worker, the error object displays as `[Object object]`. To address this issue, we reconstruct the error message. See: #27251 (cherry picked from commit 51debcd)
1 parent de2d050 commit 5707578

File tree

4 files changed

+38
-12
lines changed

4 files changed

+38
-12
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import { assertIsError } from '../error';
10+
import { loadEsmModule } from '../load-esm';
11+
import { MainServerBundleExports, RenderUtilsServerBundleExports } from './main-bundle-exports';
12+
13+
export function loadEsmModuleFromMemory(
14+
path: './main.server.mjs',
15+
): Promise<MainServerBundleExports>;
16+
export function loadEsmModuleFromMemory(
17+
path: './render-utils.server.mjs',
18+
): Promise<RenderUtilsServerBundleExports>;
19+
export function loadEsmModuleFromMemory(path: string): Promise<unknown> {
20+
return loadEsmModule(new URL(path, 'memory://')).catch((e) => {
21+
assertIsError(e);
22+
23+
// While the error is an 'instanceof Error', it is extended with non transferable properties
24+
// and cannot be transferred from a worker when using `--import`. This results in the error object
25+
// displaying as '[Object object]' when read outside of the worker. Therefore, we reconstruct the error message here.
26+
const error: Error & { code?: string } = new Error(e.message);
27+
error.stack = e.stack;
28+
error.name = e.name;
29+
error.code = e.code;
30+
31+
throw error;
32+
});
33+
}

packages/angular_devkit/build_angular/src/utils/server-rendering/render-page.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import type { ApplicationRef, StaticProvider } from '@angular/core';
1010
import assert from 'node:assert';
1111
import { basename } from 'node:path';
12-
import { loadEsmModule } from '../load-esm';
12+
import { loadEsmModuleFromMemory } from './load-esm-from-memory';
1313
import { MainServerBundleExports, RenderUtilsServerBundleExports } from './main-bundle-exports';
1414

1515
export interface RenderOptions {
@@ -39,7 +39,7 @@ export async function renderPage({
3939
document,
4040
inlineCriticalCss,
4141
outputFiles,
42-
loadBundle = loadEsmModule,
42+
loadBundle = loadEsmModuleFromMemory,
4343
}: RenderOptions): Promise<RenderResult> {
4444
const { default: bootstrapAppFnOrModule } = await loadBundle('./main.server.mjs');
4545
const { ɵSERVER_CONTEXT, renderModule, renderApplication, ɵresetCompiledComponents, ɵConsole } =

packages/angular_devkit/build_angular/src/utils/server-rendering/render-worker.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
*/
88

99
import { workerData } from 'node:worker_threads';
10-
import { loadEsmModule } from '../load-esm';
1110
import type { ESMInMemoryFileLoaderWorkerData } from './esm-in-memory-loader/loader-hooks';
1211
import { patchFetchToLoadInMemoryAssets } from './fetch-patch';
1312
import { RenderResult, ServerContext, renderPage } from './render-page';
@@ -35,7 +34,6 @@ function render(options: RenderOptions): Promise<RenderResult> {
3534
outputFiles,
3635
document,
3736
inlineCriticalCss,
38-
loadBundle: async (path) => await loadEsmModule(new URL(path, 'memory://')),
3937
});
4038
}
4139

packages/angular_devkit/build_angular/src/utils/server-rendering/routes-extractor-worker.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77
*/
88

99
import { workerData } from 'node:worker_threads';
10-
import { loadEsmModule } from '../load-esm';
1110
import type { ESMInMemoryFileLoaderWorkerData } from './esm-in-memory-loader/loader-hooks';
1211
import { patchFetchToLoadInMemoryAssets } from './fetch-patch';
13-
import { MainServerBundleExports, RenderUtilsServerBundleExports } from './main-bundle-exports';
12+
import { loadEsmModuleFromMemory } from './load-esm-from-memory';
1413

1514
export interface RoutesExtractorWorkerData extends ESMInMemoryFileLoaderWorkerData {
1615
document: string;
@@ -30,12 +29,8 @@ const { document, verbose } = workerData as RoutesExtractorWorkerData;
3029

3130
/** Renders an application based on a provided options. */
3231
async function extractRoutes(): Promise<RoutersExtractorWorkerResult> {
33-
const { extractRoutes } = await loadEsmModule<RenderUtilsServerBundleExports>(
34-
new URL('./render-utils.server.mjs', 'memory://'),
35-
);
36-
const { default: bootstrapAppFnOrModule } = await loadEsmModule<MainServerBundleExports>(
37-
new URL('./main.server.mjs', 'memory://'),
38-
);
32+
const { extractRoutes } = await loadEsmModuleFromMemory('./render-utils.server.mjs');
33+
const { default: bootstrapAppFnOrModule } = await loadEsmModuleFromMemory('./main.server.mjs');
3934

4035
const skippedRedirects: string[] = [];
4136
const skippedOthers: string[] = [];

0 commit comments

Comments
 (0)