Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/aws-cdk-lib/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ const enableNoThrowDefaultErrorIn = [
'aws-codebuild',
'aws-codecommit',
'aws-codedeploy',
'aws-codepipeline',
'aws-codepipeline-actions',
'aws-cognito',
'aws-ecr',
'aws-elasticloadbalancing',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ abstract class CloudFormationDeployAction extends CloudFormationAction {
if (this._deploymentRole) {
return this._deploymentRole;
} else {
throw new Error(`Cannot use the ${member} before the Action has been added to a Pipeline`);
throw new cdk.UnscopedValidationError(`Cannot use the ${member} before the Action has been added to a Pipeline`);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export abstract class StackInstances {
*/
public static fromArtifactPath(artifactPath: codepipeline.ArtifactPath, regions: string[]): StackInstances {
if (regions.length === 0) {
throw new Error("'regions' may not be an empty list");
throw new cdk.UnscopedValidationError("'regions' may not be an empty list");
}

return new class extends StackInstances {
Expand All @@ -159,11 +159,11 @@ export abstract class StackInstances {
*/
private static fromList(targets: string[], regions: string[]): StackInstances {
if (targets.length === 0) {
throw new Error("'targets' may not be an empty list");
throw new cdk.UnscopedValidationError("'targets' may not be an empty list");
}

if (regions.length === 0) {
throw new Error("'regions' may not be an empty list");
throw new cdk.UnscopedValidationError("'regions' may not be an empty list");
}

return new class extends StackInstances {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,12 @@ export class CodeBuildAction extends Action {
const pipelineStack = cdk.Stack.of(scope);
const projectStack = cdk.Stack.of(this.props.project);
if (pipelineStack.account !== projectStack.account) {
throw new Error('A cross-account CodeBuild action cannot have outputs. ' +
throw new cdk.ValidationError(
'A cross-account CodeBuild action cannot have outputs. ' +
'This is a known CodeBuild limitation. ' +
'See https://github.com/aws/aws-cdk/issues/4169 for details');
'See https://github.com/aws/aws-cdk/issues/4169 for details',
scope,
);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as codepipeline from '../../../aws-codepipeline';
import { EventPattern, IRuleTarget } from '../../../aws-events';
import * as targets from '../../../aws-events-targets';
import * as iam from '../../../aws-iam';
import { FeatureFlags, Names, Stack, Token, TokenComparison } from '../../../core';
import { FeatureFlags, Names, Stack, Token, TokenComparison, UnscopedValidationError } from '../../../core';
import { CODECOMMIT_SOURCE_ACTION_DEFAULT_BRANCH_NAME } from '../../../cx-api';
import { Action } from '../action';
import { sourceArtifactBounds } from '../common';
Expand Down Expand Up @@ -169,7 +169,7 @@ export class CodeCommitSourceAction extends Action {
constructor(props: CodeCommitSourceActionProps) {
const branch = props.branch ?? CodeCommitSourceAction.OLD_DEFAULT_BRANCH_NAME;
if (!branch) {
throw new Error("'branch' parameter cannot be an empty string");
throw new UnscopedValidationError("'branch' parameter cannot be an empty string");
}

if (props.codeBuildCloneOutput === true) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Construct } from 'constructs';
import * as codedeploy from '../../../aws-codedeploy';
import * as codepipeline from '../../../aws-codepipeline';
import * as iam from '../../../aws-iam';
import { Lazy } from '../../../core';
import { Lazy, UnscopedValidationError } from '../../../core';
import { Action } from '../action';
import { forceSupportStackDependency } from '../private/stack-dependency';

Expand Down Expand Up @@ -117,7 +117,7 @@ export class CodeDeployEcsDeployAction extends Action {

if (props.containerImageInputs) {
if (props.containerImageInputs.length > 4) {
throw new Error(`Action cannot have more than 4 container image inputs, got: ${props.containerImageInputs.length}`);
throw new UnscopedValidationError(`Action cannot have more than 4 container image inputs, got: ${props.containerImageInputs.length}`);
}

for (const imageInput of props.containerImageInputs) {
Expand Down Expand Up @@ -215,26 +215,26 @@ export class CodeDeployEcsDeployAction extends Action {

function determineTaskDefinitionArtifact(props: CodeDeployEcsDeployActionProps): codepipeline.Artifact {
if (props.taskDefinitionTemplateFile && props.taskDefinitionTemplateInput) {
throw new Error("Exactly one of 'taskDefinitionTemplateInput' or 'taskDefinitionTemplateFile' can be provided in the ECS CodeDeploy Action");
throw new UnscopedValidationError("Exactly one of 'taskDefinitionTemplateInput' or 'taskDefinitionTemplateFile' can be provided in the ECS CodeDeploy Action");
}
if (props.taskDefinitionTemplateFile) {
return props.taskDefinitionTemplateFile.artifact;
}
if (props.taskDefinitionTemplateInput) {
return props.taskDefinitionTemplateInput;
}
throw new Error("Specifying one of 'taskDefinitionTemplateInput' or 'taskDefinitionTemplateFile' is required for the ECS CodeDeploy Action");
throw new UnscopedValidationError("Specifying one of 'taskDefinitionTemplateInput' or 'taskDefinitionTemplateFile' is required for the ECS CodeDeploy Action");
}

function determineAppSpecArtifact(props: CodeDeployEcsDeployActionProps): codepipeline.Artifact {
if (props.appSpecTemplateFile && props.appSpecTemplateInput) {
throw new Error("Exactly one of 'appSpecTemplateInput' or 'appSpecTemplateFile' can be provided in the ECS CodeDeploy Action");
throw new UnscopedValidationError("Exactly one of 'appSpecTemplateInput' or 'appSpecTemplateFile' can be provided in the ECS CodeDeploy Action");
}
if (props.appSpecTemplateFile) {
return props.appSpecTemplateFile.artifact;
}
if (props.appSpecTemplateInput) {
return props.appSpecTemplateInput;
}
throw new Error("Specifying one of 'appSpecTemplateInput' or 'appSpecTemplateFile' is required for the ECS CodeDeploy Action");
throw new UnscopedValidationError("Specifying one of 'appSpecTemplateInput' or 'appSpecTemplateFile' is required for the ECS CodeDeploy Action");
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,11 @@ export class CommandsAction extends Action {
});

if (props.commands.length < 1 || props.commands.length > 50) {
throw new Error(`The length of the commands array must be between 1 and 50, got: ${props.commands.length}`);
throw new cdk.UnscopedValidationError(`The length of the commands array must be between 1 and 50, got: ${props.commands.length}`);
}

if (props.outputVariables !== undefined && (props.outputVariables.length < 1 || props.outputVariables.length > 15)) {
throw new Error(`The length of the outputVariables array must be between 1 and 15, got: ${props.outputVariables.length}`);
throw new cdk.UnscopedValidationError(`The length of the outputVariables array must be between 1 and 15, got: ${props.outputVariables.length}`);
}

this.outputVariables = props.outputVariables || [];
Expand All @@ -89,7 +89,7 @@ export class CommandsAction extends Action {
*/
public variable(variableName: string): string {
if (!this.outputVariables.includes(variableName)) {
throw new Error(`Variable '${variableName}' is not exported by \`outputVariables\`, exported variables: ${this.outputVariables.join(', ')}`);
throw new cdk.UnscopedValidationError(`Variable '${variableName}' is not exported by \`outputVariables\`, exported variables: ${this.outputVariables.join(', ')}`);
}
return this.variableExpression(variableName);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/aws-cdk-lib/aws-codepipeline-actions/lib/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as codepipeline from '../../aws-codepipeline';
import { Token } from '../../core';
import { Token, UnscopedValidationError } from '../../core';

/**
* The ArtifactBounds that make sense for source Actions -
Expand Down Expand Up @@ -33,6 +33,6 @@ export function validatePercentage(name: string, value?: number) {
}

if (value < 0 || value > 100 || !Number.isInteger(value)) {
throw new Error(`'${name}': must be a whole number between 0 and 100, got: ${value}`);
throw new UnscopedValidationError(`'${name}': must be a whole number between 0 and 100, got: ${value}`);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Construct } from 'constructs';
import * as codepipeline from '../../../aws-codepipeline';
import * as ecs from '../../../aws-ecs';
import * as iam from '../../../aws-iam';
import { Duration } from '../../../core';
import { Duration, UnscopedValidationError } from '../../../core';
import { Action } from '../action';
import { deployArtifactBounds } from '../common';

Expand Down Expand Up @@ -70,7 +70,7 @@ export class EcsDeployAction extends Action {

const deploymentTimeout = props.deploymentTimeout?.toMinutes({ integral: true });
if (deploymentTimeout !== undefined && (deploymentTimeout < 1 || deploymentTimeout > 60)) {
throw new Error(`Deployment timeout must be between 1 and 60 minutes, got: ${deploymentTimeout}`);
throw new UnscopedValidationError(`Deployment timeout must be between 1 and 60 minutes, got: ${deploymentTimeout}`);
}

this.props = props;
Expand Down Expand Up @@ -122,13 +122,13 @@ export class EcsDeployAction extends Action {

function determineInputArtifact(props: EcsDeployActionProps): codepipeline.Artifact {
if (props.imageFile && props.input) {
throw new Error("Exactly one of 'input' or 'imageFile' can be provided in the ECS deploy Action");
throw new UnscopedValidationError("Exactly one of 'input' or 'imageFile' can be provided in the ECS deploy Action");
}
if (props.imageFile) {
return props.imageFile.artifact;
}
if (props.input) {
return props.input;
}
throw new Error("Specifying one of 'input' or 'imageFile' is required for the ECS deploy Action");
throw new UnscopedValidationError("Specifying one of 'input' or 'imageFile' is required for the ECS deploy Action");
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Construct } from 'constructs';
import * as codepipeline from '../../../aws-codepipeline';
import * as iam from '../../../aws-iam';
import * as lambda from '../../../aws-lambda';
import { Stack } from '../../../core';
import { Stack, UnscopedValidationError } from '../../../core';
import { Action } from '../action';

/**
Expand Down Expand Up @@ -84,7 +84,7 @@ export class LambdaInvokeAction extends Action {
this.props = props;

if (props.userParameters && props.userParametersString) {
throw new Error('Only one of userParameters or userParametersString can be specified');
throw new UnscopedValidationError('Only one of userParameters or userParametersString can be specified');
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as codepipeline from '../../aws-codepipeline';
import * as iam from '../../aws-iam';
import * as sns from '../../aws-sns';
import * as subs from '../../aws-sns-subscriptions';
import { Duration } from '../../core';
import { Duration, UnscopedValidationError } from '../../core';

/**
* Construction properties of the `ManualApprovalAction`.
Expand Down Expand Up @@ -67,7 +67,7 @@ export class ManualApprovalAction extends Action {
});

if (props.timeout && (props.timeout.toMinutes() < 5 || props.timeout.toMinutes() > 86400)) {
throw new Error(`timeout must be between 5 minutes and 86400 minutes (60 days), got ${props.timeout.toMinutes()} minutes`);
throw new UnscopedValidationError(`timeout must be between 5 minutes and 86400 minutes (60 days), got ${props.timeout.toMinutes()} minutes`);
}

this.props = props;
Expand All @@ -87,7 +87,7 @@ export class ManualApprovalAction extends Action {
*/
public grantManualApproval(grantable: iam.IGrantable): void {
if (!this.stage) {
throw new Error('Cannot grant permissions before binding action to a stage');
throw new UnscopedValidationError('Cannot grant permissions before binding action to a stage');
}
grantable.grantPrincipal.addToPrincipalPolicy(new iam.PolicyStatement({
actions: ['codepipeline:ListPipelines'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Construct } from 'constructs';
import * as codepipeline from '../../../aws-codepipeline';
import * as targets from '../../../aws-events-targets';
import * as s3 from '../../../aws-s3';
import { Names, Token } from '../../../core';
import { Names, Token, UnscopedValidationError } from '../../../core';
import { Action } from '../action';
import { sourceArtifactBounds } from '../common';

Expand Down Expand Up @@ -97,7 +97,7 @@ export class S3SourceAction extends Action {
});

if (props.bucketKey.length === 0) {
throw new Error('Property bucketKey cannot be an empty string');
throw new UnscopedValidationError('Property bucketKey cannot be an empty string');
}

this.props = props;
Expand Down Expand Up @@ -159,7 +159,7 @@ export class S3SourceAction extends Action {
ret = baseId + this.props.bucketKey;
if (this.props.bucket.node.tryFindChild(ret)) {
// this means a duplicate path for the same bucket - error out
throw new Error(`S3 source action with path '${this.props.bucketKey}' is already present in the pipeline for this source bucket`);
throw new UnscopedValidationError(`S3 source action with path '${this.props.bucketKey}' is already present in the pipeline for this source bucket`);
}
}

Expand Down
11 changes: 5 additions & 6 deletions packages/aws-cdk-lib/aws-codepipeline/lib/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as notifications from '../../aws-codestarnotifications';
import * as events from '../../aws-events';
import * as iam from '../../aws-iam';
import * as s3 from '../../aws-s3';
import { Duration, IResource, Lazy } from '../../core';
import { Duration, IResource, Lazy, UnscopedValidationError } from '../../core';

export enum ActionCategory {
SOURCE = 'Source',
Expand Down Expand Up @@ -398,8 +398,7 @@ export abstract class Action implements IAction {
produce: () => {
// make sure the action was bound (= added to a pipeline)
if (this._actualNamespace === undefined) {
throw new Error(`Cannot reference variables of action '${this.actionProperties.actionName}', ` +
'as that action was never added to a pipeline');
throw new UnscopedValidationError(`Cannot reference variables of action '${this.actionProperties.actionName}', as that action was never added to a pipeline`);
} else {
return this._customerProvidedNamespace !== undefined
// if a customer passed a namespace explicitly, always use that
Expand Down Expand Up @@ -467,15 +466,15 @@ export abstract class Action implements IAction {
if (this.__pipeline) {
return this.__pipeline;
} else {
throw new Error('Action must be added to a stage that is part of a pipeline before using onStateChange');
throw new UnscopedValidationError('Action must be added to a stage that is part of a pipeline before using onStateChange');
}
}

private get _stage(): IStage {
if (this.__stage) {
return this.__stage;
} else {
throw new Error('Action must be added to a stage that is part of a pipeline before using onStateChange');
throw new UnscopedValidationError('Action must be added to a stage that is part of a pipeline before using onStateChange');
}
}

Expand All @@ -488,7 +487,7 @@ export abstract class Action implements IAction {
if (this.__scope) {
return this.__scope;
} else {
throw new Error('Action must be added to a stage that is part of a pipeline first');
throw new UnscopedValidationError('Action must be added to a stage that is part of a pipeline first');
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/aws-cdk-lib/aws-codepipeline/lib/artifact.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as validation from './private/validation';
import * as s3 from '../../aws-s3';
import { Lazy, Token } from '../../core';
import { Lazy, Token, UnscopedValidationError } from '../../core';

/**
* An output artifact of an action. Artifacts can be used as input by some actions.
Expand Down Expand Up @@ -35,7 +35,7 @@ export class Artifact {
validation.validateArtifactName(artifactName);

if (artifactFiles !== undefined && (artifactFiles.length < 1 || artifactFiles.length > 10)) {
throw new Error(`The length of the artifactFiles array must be between 1 and 10, got: ${artifactFiles.length}`);
throw new UnscopedValidationError(`The length of the artifactFiles array must be between 1 and 10, got: ${artifactFiles.length}`);
}

this._artifactName = artifactName;
Expand Down Expand Up @@ -133,7 +133,7 @@ export class Artifact {
/** @internal */
protected _setName(name: string) {
if (this._artifactName) {
throw new Error(`Artifact already has name '${this._artifactName}', cannot override it`);
throw new UnscopedValidationError(`Artifact already has name '${this._artifactName}', cannot override it`);
} else {
this._artifactName = name;
}
Expand Down
Loading