mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-17 19:13:34 +08:00
fix(@angular/cli): avoid exceptions for expected errors in architect commands
Errors caused by invalid options or workspace configuration will now be presented as fatal console messages and the CLI will exit gracefully with an exit code of 1.
This commit is contained in:
parent
af1cc2d642
commit
06335515eb
@ -28,11 +28,7 @@ export class DeployCommand extends ArchitectCommand<DeployCommandSchema> {
|
||||
public readonly target = 'deploy';
|
||||
public readonly missingTargetError = BuilderMissing;
|
||||
|
||||
public async run(options: ArchitectCommandOptions & Arguments) {
|
||||
return this.runArchitectTarget(options);
|
||||
}
|
||||
|
||||
public async initialize(options: DeployCommandSchema & Arguments): Promise<void> {
|
||||
public async initialize(options: DeployCommandSchema & Arguments): Promise<number | void> {
|
||||
if (!options.help) {
|
||||
return super.initialize(options);
|
||||
}
|
||||
|
@ -35,15 +35,15 @@ export abstract class ArchitectCommand<
|
||||
target: string | undefined;
|
||||
missingTargetError: string | undefined;
|
||||
|
||||
public async initialize(options: T & Arguments): Promise<void> {
|
||||
await super.initialize(options);
|
||||
|
||||
public async initialize(options: T & Arguments): Promise<number | void> {
|
||||
this._registry = new json.schema.CoreSchemaRegistry();
|
||||
this._registry.addPostTransform(json.schema.transforms.addUndefinedDefaults);
|
||||
this._registry.useXDeprecatedProvider(msg => this.logger.warn(msg));
|
||||
|
||||
if (!this.workspace) {
|
||||
throw new Error('A workspace is required for an architect command.');
|
||||
this.logger.fatal('A workspace is required for this command.');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
this._architectHost = new WorkspaceNodeModulesArchitectHost(this.workspace, this.workspace.basePath);
|
||||
@ -57,7 +57,9 @@ export abstract class ArchitectCommand<
|
||||
|
||||
const specifier = this._makeTargetSpecifier(options);
|
||||
if (!specifier.project || !specifier.target) {
|
||||
throw new Error('Cannot determine project or target for command.');
|
||||
this.logger.fatal('Cannot determine project or target for command.');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return;
|
||||
@ -65,7 +67,9 @@ export abstract class ArchitectCommand<
|
||||
|
||||
let projectName = options.project;
|
||||
if (projectName && !this.workspace.projects.has(projectName)) {
|
||||
throw new Error(`Project '${projectName}' does not exist.`);
|
||||
this.logger.fatal(`Project '${projectName}' does not exist.`);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const commandLeftovers = options['--'];
|
||||
@ -77,12 +81,16 @@ export abstract class ArchitectCommand<
|
||||
}
|
||||
|
||||
if (targetProjectNames.length === 0) {
|
||||
throw new Error(this.missingTargetError || `No projects support the '${this.target}' target.`);
|
||||
this.logger.fatal(this.missingTargetError || `No projects support the '${this.target}' target.`);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (projectName && !targetProjectNames.includes(projectName)) {
|
||||
throw new Error(this.missingTargetError ||
|
||||
this.logger.fatal(this.missingTargetError ||
|
||||
`Project '${projectName}' does not support the '${this.target}' target.`);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!projectName && commandLeftovers && commandLeftovers.length > 0) {
|
||||
@ -141,11 +149,13 @@ export abstract class ArchitectCommand<
|
||||
}
|
||||
|
||||
if (!projectName && this.multiTarget && builderNames.size > 1) {
|
||||
throw new Error(tags.oneLine`
|
||||
this.logger.fatal(tags.oneLine`
|
||||
Architect commands with command line overrides cannot target different builders. The
|
||||
'${this.target}' target would run on projects ${targetProjectNames.join()} which have the
|
||||
following builders: ${'\n ' + [...builderNames].join('\n ')}
|
||||
`);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +169,9 @@ export abstract class ArchitectCommand<
|
||||
// This is a special case where we just return.
|
||||
return;
|
||||
} else {
|
||||
throw new Error(this.missingTargetError || 'Cannot determine project or target for command.');
|
||||
this.logger.fatal(this.missingTargetError || 'Cannot determine project or target for command.');
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -42,9 +42,7 @@ export abstract class Command<T extends BaseCommandOptions = BaseCommandOptions>
|
||||
this.analytics = context.analytics || new analytics.NoopAnalytics();
|
||||
}
|
||||
|
||||
async initialize(options: T & Arguments): Promise<void> {
|
||||
return;
|
||||
}
|
||||
async initialize(options: T & Arguments): Promise<number | void> {}
|
||||
|
||||
async printHelp(): Promise<number> {
|
||||
await this.printHelpUsage();
|
||||
@ -169,7 +167,10 @@ export abstract class Command<T extends BaseCommandOptions = BaseCommandOptions>
|
||||
if (!(options.help === true || options.help === 'json' || options.help === 'JSON')) {
|
||||
await this.validateScope();
|
||||
}
|
||||
await this.initialize(options);
|
||||
let result = await this.initialize(options);
|
||||
if (typeof result === 'number' && result !== 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (options.help === true) {
|
||||
return this.printHelp();
|
||||
@ -180,7 +181,7 @@ export abstract class Command<T extends BaseCommandOptions = BaseCommandOptions>
|
||||
if (this.useReportAnalytics) {
|
||||
await this.reportAnalytics([this.description.name], options);
|
||||
}
|
||||
const result = await this.run(options);
|
||||
result = await this.run(options);
|
||||
const endTime = +new Date();
|
||||
|
||||
this.analytics.timing(this.description.name, 'duration', endTime - startTime);
|
||||
|
Loading…
x
Reference in New Issue
Block a user