Skip to content

Commit

Permalink
fix(@angular/ssr): correct route extraction and error handling
Browse files Browse the repository at this point in the history
This commit introduces the following changes:
- Disallows paths starting with a slash to match Angular router behavior.
- Errors are now stored and displayed at a later stage, improving UX by avoiding unnecessary stack traces that are not useful in this context.
  • Loading branch information
alan-agius4 committed Sep 16, 2024
1 parent d60f3fe commit 2640bf7
Show file tree
Hide file tree
Showing 12 changed files with 365 additions and 165 deletions.
20 changes: 11 additions & 9 deletions packages/angular/build/src/utils/server-rendering/prerender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import { BuildOutputAsset } from '../../tools/esbuild/bundler-execution-result';
import { urlJoin } from '../url';
import type { RenderWorkerData } from './render-worker';
import type {
RoutersExtractorWorkerResult,
RoutesExtractorWorkerData,
RoutersExtractorWorkerResult as SerializableRouteTreeNode,
SerializableRouteTreeNode,
} from './routes-extractor-worker';

interface PrerenderOptions {
Expand Down Expand Up @@ -298,14 +299,15 @@ async function getAllRoutes(
});

const errors: string[] = [];
const serializableRouteTreeNode: SerializableRouteTreeNode = await renderWorker
.run({})
.catch((err) => {
errors.push(`An error occurred while extracting routes.\n\n${err.stack}`);
})
.finally(() => {
void renderWorker.destroy();
});
const { serializedRouteTree: serializableRouteTreeNode }: RoutersExtractorWorkerResult =
await renderWorker
.run({})
.catch((err) => {
errors.push(`An error occurred while extracting routes.\n\n${err.stack}`);
})
.finally(() => {
void renderWorker.destroy();
});

const skippedRedirects: string[] = [];
const skippedOthers: string[] = [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,30 @@ export interface RoutesExtractorWorkerData extends ESMInMemoryFileLoaderWorkerDa
assetFiles: Record</** Destination */ string, /** Source */ string>;
}

export type RoutersExtractorWorkerResult = ReturnType<
Awaited<ReturnType<typeof ɵextractRoutesAndCreateRouteTree>>['toObject']
export type SerializableRouteTreeNode = ReturnType<
Awaited<ReturnType<typeof ɵextractRoutesAndCreateRouteTree>>['routeTree']['toObject']
>;

export interface RoutersExtractorWorkerResult {
serializedRouteTree: SerializableRouteTreeNode;
errors: string[];
}

/** Renders an application based on a provided options. */
async function extractRoutes(): Promise<RoutersExtractorWorkerResult> {
const { ɵextractRoutesAndCreateRouteTree: extractRoutesAndCreateRouteTree } =
await loadEsmModuleFromMemory('./main.server.mjs');

const routeTree = await extractRoutesAndCreateRouteTree(
const { routeTree, errors } = await extractRoutesAndCreateRouteTree(
new URL('http://local-angular-prerender/'),
/** manifest */ undefined,
/** invokeGetPrerenderParams */ true,
);

return routeTree.toObject();
return {
errors,
serializedRouteTree: routeTree.toObject(),
};
}

function initialize() {
Expand Down
2 changes: 1 addition & 1 deletion packages/angular/ssr/node/src/app-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export class AngularNodeAppEngine {
* const headers = angularAppEngine.getPrerenderHeaders(res.req);
*
* // Apply the retrieved headers to the response
* for (const { key, value } of headers) {
* for (const [key, value] of headers) {
* res.setHeader(key, value);
* }
* }
Expand Down
Loading

0 comments on commit 2640bf7

Please sign in to comment.