Skip to content

Commit

Permalink
fix(@angular/cli): print ng update errors stack to log file
Browse files Browse the repository at this point in the history
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)
```
  • Loading branch information
alan-agius4 authored and Keen Yee Liau committed Feb 18, 2020
1 parent efaaaed commit 9188467
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 11 deletions.
11 changes: 7 additions & 4 deletions packages/angular/cli/commands/update-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { Command } from '../models/command';
import { Arguments } from '../models/interface';
import { runTempPackageBin } from '../tasks/install-package';
import { colors } from '../utilities/color';
import { writeErrorToLogFile } from '../utilities/log-file';
import { getPackageManager } from '../utilities/package-manager';
import {
PackageIdentifier,
Expand Down Expand Up @@ -141,9 +142,13 @@ export class UpdateCommand extends Command<UpdateCommandSchema> {
return { success: !error, files };
} catch (e) {
if (e instanceof UnsuccessfulWorkflowExecution) {
this.logger.error('The update failed. See above.');
this.logger.error(`${colors.symbols.cross} Migration failed. See above for further details.\n`);
} else {
this.logger.fatal(e.message);
const logPath = writeErrorToLogFile(e);
this.logger.fatal(
`${colors.symbols.cross} Migration failed: ${e.message}\n` +
` See "${logPath}" for further details.\n`,
);
}

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

const result = await this.executeSchematic(migration.collection.name, migration.name);
if (!result.success) {
this.logger.error(`${colors.symbols.cross} Migration failed. See above for further details.\n`);

return false;
}

Expand Down
9 changes: 2 additions & 7 deletions packages/angular/cli/lib/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
* found in the LICENSE file at https://angular.io/license
*/
import { createConsoleLogger } from '@angular-devkit/core/node';
import { normalize } from 'path';
import { format } from 'util';
import { runCommand } from '../../models/command-runner';
import { colors, supportsColor } from '../../utilities/color';
import { getWorkspaceRaw } from '../../utilities/config';
import { writeErrorToLogFile } from '../../utilities/log-file';
import { getWorkspaceDetails } from '../../utilities/project';

const debugEnv = process.env['NG_DEBUG'];
Expand Down Expand Up @@ -82,12 +82,7 @@ export default async function(options: { testing?: boolean; cliArgs: string[] })
} catch (err) {
if (err instanceof Error) {
try {
const fs = await import('fs');
const os = await import('os');
const tempDirectory = fs.mkdtempSync(fs.realpathSync(os.tmpdir()) + '/' + 'ng-');
const logPath = normalize(tempDirectory + '/angular-errors.log');
fs.appendFileSync(logPath, '[error] ' + (err.stack || err));

const logPath = writeErrorToLogFile(err);
logger.fatal(
`An unhandled exception occurred: ${err.message}\n` +
`See "${logPath}" for further details.`,
Expand Down
29 changes: 29 additions & 0 deletions packages/angular/cli/utilities/log-file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import { appendFileSync, mkdtempSync, realpathSync } from 'fs';
import { tmpdir } from 'os';
import { normalize } from 'path';

let logPath: string | undefined;

/**
* Writes an Error to a temporary log file.
* If this method is called multiple times from the same process the same log file will be used.
* @returns The path of the generated log file.
*/
export function writeErrorToLogFile(error: Error): string {
if (!logPath) {
const tempDirectory = mkdtempSync(realpathSync(tmpdir()) + '/ng-');
logPath = normalize(tempDirectory + '/angular-errors.log');
}

appendFileSync(logPath, '[error] ' + (error.stack || error) + '\n\n');

return logPath;
}

0 comments on commit 9188467

Please sign in to comment.