Skip to content

Commit 79fb758

Browse files
crisbetommalerba
authored andcommitted
build: fail build for prerender errors in lifecycle hooks (#5459)
* Currently the build won't fail if an error is thrown inside a lifecycle hook, because `platform-server` writes it to STDERR, but still exits with a 0 code. These changes set up the Universal testing task to fail for these cases as well. This should prevent issues like #5455 in the future. * Stops logging the entire rendered document after the prerender task is done. This makes the log a bit easier to look through.
1 parent 0675568 commit 79fb758

File tree

3 files changed

+16
-11
lines changed

3 files changed

+16
-11
lines changed

src/universal-app/prerender.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {enableProdMode} from '@angular/core';
55
import {renderModuleFactory} from '@angular/platform-server';
66
import {join} from 'path';
77
import {readFileSync} from 'fs-extra';
8+
import {log} from 'gulp-util';
89
import {KitchenSinkServerModuleNgFactory} from './kitchen-sink/kitchen-sink.ngfactory';
910

1011
enableProdMode();
@@ -14,7 +15,7 @@ const result = renderModuleFactory(KitchenSinkServerModuleNgFactory, {
1415
});
1516

1617
result
17-
.then(html => console.log(html))
18+
.then(() => log('Prerender done.'))
1819
// If rendering the module factory fails, exit the process with an error code because otherwise
1920
// the CI task will not recognize the failure and will show as "success". The error message
2021
// will be printed automatically by the `renderModuleFactory` method.

tools/gulp/tasks/universal.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ const prerenderOutFile = join(outDir, 'prerender.js');
2525
task('universal:test-prerender', ['universal:build'], execTask(
2626
// Runs node with the tsconfig-paths module to alias the @angular/material dependency.
2727
'node', ['-r', 'tsconfig-paths/register', prerenderOutFile], {
28-
env: {TS_NODE_PROJECT: tsconfigPrerenderPath}
28+
env: {TS_NODE_PROJECT: tsconfigPrerenderPath},
29+
// Errors in lifecycle hooks will write to STDERR, but won't exit the process with an
30+
// error code, however we still want to catch those cases in the CI.
31+
failOnStderr: true
2932
}
3033
));
3134

tools/gulp/util/task_helpers.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,31 +49,32 @@ export interface ExecTaskOptions {
4949
errMessage?: string;
5050
// Environment variables being passed to the child process.
5151
env?: any;
52+
// Whether the task should fail if the process writes to STDERR.
53+
failOnStderr?: boolean;
5254
}
5355

5456
/** Create a task that executes a binary as if from the command line. */
5557
export function execTask(binPath: string, args: string[], options: ExecTaskOptions = {}) {
5658
return (done: (err?: string) => void) => {
5759
const env = Object.assign({}, process.env, options.env);
5860
const childProcess = child_process.spawn(binPath, args, {env});
61+
const stderrData: string[] = [];
5962

6063
if (!options.silentStdout && !options.silent) {
6164
childProcess.stdout.on('data', (data: string) => process.stdout.write(data));
6265
}
6366

64-
if (!options.silent) {
65-
childProcess.stderr.on('data', (data: string) => process.stderr.write(data));
67+
if (!options.silent || options.failOnStderr) {
68+
childProcess.stderr.on('data', (data: string) => {
69+
options.failOnStderr ? stderrData.push(data) : process.stderr.write(data);
70+
});
6671
}
6772

6873
childProcess.on('close', (code: number) => {
69-
if (code != 0) {
70-
if (options.errMessage === undefined) {
71-
done('Process failed with code ' + code);
72-
} else {
73-
done(options.errMessage);
74-
}
74+
if (options.failOnStderr && stderrData.length) {
75+
done(stderrData.join('\n'));
7576
} else {
76-
done();
77+
code != 0 ? done(options.errMessage || `Process failed with code ${code}`) : done();
7778
}
7879
});
7980
};

0 commit comments

Comments
 (0)