Skip to content

Commit 59b69f5

Browse files
committed
fix(@angular/build): add a maximum rendering timeout for SSG
There might be cases were currently, the render application promise does not resolve because the application never becomes stable in most cases this is due to errors, this causes the worker to never exit and the build to keep running until it's manually terminated. With this change, we add a maximum rendering timeout of 30seconds for each page. Closes #27565
1 parent abf18a6 commit 59b69f5

File tree

2 files changed

+24
-3
lines changed

2 files changed

+24
-3
lines changed

packages/angular/build/src/utils/server-rendering/render-page.ts

+23-3
Original file line numberDiff line numberDiff line change
@@ -73,26 +73,46 @@ export async function renderPage({
7373
},
7474
];
7575

76-
let html: string | undefined;
7776
assert(
7877
bootstrapAppFnOrModule,
7978
'The file "./main.server.mjs" does not have a default export for an AppServerModule or a bootstrapping function.',
8079
);
8180

81+
let renderAppPromise: Promise<string>;
8282
if (isBootstrapFn(bootstrapAppFnOrModule)) {
83-
html = await renderApplication(bootstrapAppFnOrModule, {
83+
renderAppPromise = renderApplication(bootstrapAppFnOrModule, {
8484
document,
8585
url: route,
8686
platformProviders,
8787
});
8888
} else {
89-
html = await renderModule(bootstrapAppFnOrModule, {
89+
renderAppPromise = renderModule(bootstrapAppFnOrModule, {
9090
document,
9191
url: route,
9292
extraProviders: platformProviders,
9393
});
9494
}
9595

96+
// The below should really handled by the framework!!!.
97+
// See: https://github.com/angular/angular/issues/51549
98+
let timer: NodeJS.Timeout;
99+
const renderingTimeout = new Promise<never>(
100+
(_, reject) =>
101+
(timer = setTimeout(
102+
() =>
103+
reject(
104+
new Error(
105+
`Page ${new URL(route, 'resolve://').pathname} did not render in 30 seconds.`,
106+
),
107+
),
108+
30_000,
109+
)),
110+
);
111+
112+
const html = await Promise.race([renderAppPromise, renderingTimeout]).finally(() =>
113+
clearTimeout(timer),
114+
);
115+
96116
if (inlineCriticalCss) {
97117
const { InlineCriticalCssProcessor } = await import(
98118
'../../utils/index-file/inline-critical-css'

packages/angular_devkit/build_angular/src/builders/app-shell/render-worker.ts

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ async function render({ serverBundlePath, document, url }: RenderRequest): Promi
103103
}
104104

105105
// The below should really handled by the framework!!!.
106+
// See: https://github.com/angular/angular/issues/51549
106107
let timer: NodeJS.Timeout;
107108
const renderingTimeout = new Promise<never>(
108109
(_, reject) =>

0 commit comments

Comments
 (0)