Skip to content

Commit 66b218c

Browse files
alan-agius4Keen Yee Liau
authored and
Keen Yee Liau
committed
fix(@angular/cli): print ng update errors stack to log file
When an error occurs during ng update we currently discard the stack trace which in some cases made it hard to identify the cause of the error. Now, we print the stack trace to a log file similarly to unhandled exceptions. Example of CMD output; ```cmd ** Executing migrations of package '@angular/core' ** > Static flag migration. Removes the `static` flag from dynamic queries. As of Angular 9, the "static" flag defaults to false and is no longer required for your view and content queries. Read more about this here: https://v9.angular.io/guide/migration-dynamic-flag × Migration failed: x See "C:\Users\alag\AppData\Local\Temp\ng-NgmC1G\angular-errors.log" for further details. ``` Example of log file contents: ```txt [error] Error: x at UpdateCommand.executeSchematic (C:\git\angular-cli\test\node_modules\@angular\cli\commands\update-impl.js:98:19) at UpdateCommand.executePackageMigrations (C:\git\angular-cli\test\node_modules\@angular\cli\commands\update-impl.js:167:39) at UpdateCommand.executeMigrations (C:\git\angular-cli\test\node_modules\@angular\cli\commands\update-impl.js:161:21) at UpdateCommand.run (C:\git\angular-cli\test\node_modules\@angular\cli\commands\update-impl.js:394:38) at async UpdateCommand.validateAndRun (C:\git\angular-cli\test\node_modules\@angular\cli\models\command.js:134:28) at async Object.runCommand (C:\git\angular-cli\test\node_modules\@angular\cli\models\command-runner.js:201:24) at async default_1 (C:\git\angular-cli\test\node_modules\@angular\cli\lib\cli\index.js:62:31) ```
1 parent 37f2090 commit 66b218c

File tree

3 files changed

+38
-11
lines changed

3 files changed

+38
-11
lines changed

packages/angular/cli/commands/update-impl.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { Command } from '../models/command';
1818
import { Arguments } from '../models/interface';
1919
import { runTempPackageBin } from '../tasks/install-package';
2020
import { colors } from '../utilities/color';
21+
import { writeErrorToLogFile } from '../utilities/log-file';
2122
import { getPackageManager } from '../utilities/package-manager';
2223
import {
2324
PackageIdentifier,
@@ -141,9 +142,13 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
141142
return { success: !error, files };
142143
} catch (e) {
143144
if (e instanceof UnsuccessfulWorkflowExecution) {
144-
this.logger.error('The update failed. See above.');
145+
this.logger.error(`${colors.symbols.cross} Migration failed. See above for further details.\n`);
145146
} else {
146-
this.logger.fatal(e.message);
147+
const logPath = writeErrorToLogFile(e);
148+
this.logger.fatal(
149+
`${colors.symbols.cross} Migration failed: ${e.message}\n` +
150+
` See "${logPath}" for further details.\n`,
151+
);
147152
}
148153

149154
return { success: false, files };
@@ -223,8 +228,6 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
223228

224229
const result = await this.executeSchematic(migration.collection.name, migration.name);
225230
if (!result.success) {
226-
this.logger.error(`${colors.symbols.cross} Migration failed. See above for further details.\n`);
227-
228231
return false;
229232
}
230233

packages/angular/cli/lib/cli/index.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88
import { createConsoleLogger } from '@angular-devkit/core/node';
9-
import { normalize } from 'path';
109
import { format } from 'util';
1110
import { runCommand } from '../../models/command-runner';
1211
import { colors, supportsColor } from '../../utilities/color';
1312
import { getWorkspaceRaw } from '../../utilities/config';
13+
import { writeErrorToLogFile } from '../../utilities/log-file';
1414
import { getWorkspaceDetails } from '../../utilities/project';
1515

1616
const debugEnv = process.env['NG_DEBUG'];
@@ -82,12 +82,7 @@ export default async function(options: { testing?: boolean; cliArgs: string[] })
8282
} catch (err) {
8383
if (err instanceof Error) {
8484
try {
85-
const fs = await import('fs');
86-
const os = await import('os');
87-
const tempDirectory = fs.mkdtempSync(fs.realpathSync(os.tmpdir()) + '/' + 'ng-');
88-
const logPath = normalize(tempDirectory + '/angular-errors.log');
89-
fs.appendFileSync(logPath, '[error] ' + (err.stack || err));
90-
85+
const logPath = writeErrorToLogFile(err);
9186
logger.fatal(
9287
`An unhandled exception occurred: ${err.message}\n` +
9388
`See "${logPath}" for further details.`,
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* @license
3+
* Copyright Google Inc. 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 { appendFileSync, mkdtempSync, realpathSync } from 'fs';
10+
import { tmpdir } from 'os';
11+
import { normalize } from 'path';
12+
13+
let logPath: string | undefined;
14+
15+
/**
16+
* Writes an Error to a temporary log file.
17+
* If this method is called multiple times from the same process the same log file will be used.
18+
* @returns The path of the generated log file.
19+
*/
20+
export function writeErrorToLogFile(error: Error): string {
21+
if (!logPath) {
22+
const tempDirectory = mkdtempSync(realpathSync(tmpdir()) + '/ng-');
23+
logPath = normalize(tempDirectory + '/angular-errors.log');
24+
}
25+
26+
appendFileSync(logPath, '[error] ' + (error.stack || error) + '\n\n');
27+
28+
return logPath;
29+
}

0 commit comments

Comments
 (0)