diff --git a/packages/aws-cdk-lib/.eslintrc.js b/packages/aws-cdk-lib/.eslintrc.js index 8e9fc7059e236..846403c62d618 100644 --- a/packages/aws-cdk-lib/.eslintrc.js +++ b/packages/aws-cdk-lib/.eslintrc.js @@ -48,6 +48,7 @@ const enableNoThrowDefaultErrorIn = [ 'aws-cognito', 'aws-docdb', 'aws-ecr', + 'aws-efs', 'aws-elasticloadbalancing', 'aws-elasticloadbalancingv2', 'aws-elasticloadbalancingv2-actions', diff --git a/packages/aws-cdk-lib/aws-efs/lib/access-point.ts b/packages/aws-cdk-lib/aws-efs/lib/access-point.ts index 1bbcdfb2d142a..cb6edb7f9071f 100644 --- a/packages/aws-cdk-lib/aws-efs/lib/access-point.ts +++ b/packages/aws-cdk-lib/aws-efs/lib/access-point.ts @@ -1,7 +1,7 @@ import { Construct } from 'constructs'; import { IFileSystem } from './efs-file-system'; import { CfnAccessPoint } from './efs.generated'; -import { ArnFormat, IResource, Resource, Stack, Tags, Token } from '../../core'; +import { ArnFormat, IResource, Resource, Stack, Tags, Token, ValidationError } from '../../core'; import { addConstructMetadata } from '../../core/lib/metadata-resource'; /** @@ -215,7 +215,7 @@ export class AccessPoint extends AccessPointBase { const clientToken = props.clientToken; if ((clientToken?.length === 0 || (clientToken && clientToken.length > 64)) && !Token.isUnresolved(clientToken)) { - throw new Error(`The length of \'clientToken\' must range from 1 to 64 characters, got: ${clientToken.length} characters`); + throw new ValidationError(`The length of \'clientToken\' must range from 1 to 64 characters, got: ${clientToken.length} characters`, this); } const resource = new CfnAccessPoint(this, 'Resource', { @@ -260,20 +260,20 @@ class ImportedAccessPoint extends AccessPointBase { if (!attrs.accessPointId) { if (!attrs.accessPointArn) { - throw new Error('One of accessPointId or AccessPointArn is required!'); + throw new ValidationError('One of accessPointId or AccessPointArn is required!', this); } this.accessPointArn = attrs.accessPointArn; let maybeApId = Stack.of(scope).splitArn(attrs.accessPointArn, ArnFormat.SLASH_RESOURCE_NAME).resourceName; if (!maybeApId) { - throw new Error('ARN for AccessPoint must provide the resource name.'); + throw new ValidationError('ARN for AccessPoint must provide the resource name.', this); } this.accessPointId = maybeApId; } else { if (attrs.accessPointArn) { - throw new Error('Only one of accessPointId or AccessPointArn can be provided!'); + throw new ValidationError('Only one of accessPointId or AccessPointArn can be provided!', this); } this.accessPointId = attrs.accessPointId; @@ -289,7 +289,7 @@ class ImportedAccessPoint extends AccessPointBase { public get fileSystem() { if (!this._fileSystem) { - throw new Error("fileSystem is only available if 'fromAccessPointAttributes()' is used and a fileSystem is passed in as an attribute."); + throw new ValidationError("fileSystem is only available if 'fromAccessPointAttributes()' is used and a fileSystem is passed in as an attribute.", this); } return this._fileSystem; diff --git a/packages/aws-cdk-lib/aws-efs/lib/efs-file-system.ts b/packages/aws-cdk-lib/aws-efs/lib/efs-file-system.ts index c82ac513a9c29..37b775d593598 100644 --- a/packages/aws-cdk-lib/aws-efs/lib/efs-file-system.ts +++ b/packages/aws-cdk-lib/aws-efs/lib/efs-file-system.ts @@ -4,7 +4,7 @@ import { CfnFileSystem, CfnMountTarget } from './efs.generated'; import * as ec2 from '../../aws-ec2'; import * as iam from '../../aws-iam'; import * as kms from '../../aws-kms'; -import { ArnFormat, FeatureFlags, Lazy, RemovalPolicy, Resource, Size, Stack, Tags, Token } from '../../core'; +import { ArnFormat, FeatureFlags, Lazy, RemovalPolicy, Resource, Size, Stack, Tags, Token, ValidationError } from '../../core'; import { addConstructMetadata, MethodMetadata } from '../../core/lib/metadata-resource'; import * as cxapi from '../../cx-api'; @@ -735,21 +735,21 @@ export class FileSystem extends FileSystemBase { this.props = props; if (props.performanceMode === PerformanceMode.MAX_IO && props.oneZone) { - throw new Error('performanceMode MAX_IO is not supported for One Zone file systems.'); + throw new ValidationError('performanceMode MAX_IO is not supported for One Zone file systems.', this); } if (props.oneZone) { this.oneZoneValidation(); } if (props.throughputMode === ThroughputMode.PROVISIONED && props.provisionedThroughputPerSecond === undefined) { - throw new Error('Property provisionedThroughputPerSecond is required when throughputMode is PROVISIONED'); + throw new ValidationError('Property provisionedThroughputPerSecond is required when throughputMode is PROVISIONED', this); } if (props.throughputMode === ThroughputMode.ELASTIC && props.performanceMode === PerformanceMode.MAX_IO) { - throw new Error('ThroughputMode ELASTIC is not supported for file systems with performanceMode MAX_IO'); + throw new ValidationError('ThroughputMode ELASTIC is not supported for file systems with performanceMode MAX_IO', this); } if (props.replicationConfiguration && props.replicationOverwriteProtection === ReplicationOverwriteProtection.DISABLED) { - throw new Error('Cannot configure \'replicationConfiguration\' when \'replicationOverwriteProtection\' is set to \'DISABLED\''); + throw new ValidationError('Cannot configure \'replicationConfiguration\' when \'replicationOverwriteProtection\' is set to \'DISABLED\'', this); } // we explicitly use 'undefined' to represent 'false' to maintain backwards compatibility since @@ -891,13 +891,13 @@ export class FileSystem extends FileSystemBase { private oneZoneValidation() { // validate when props.oneZone is enabled if (this.props.vpcSubnets && !this.props.vpcSubnets.availabilityZones) { - throw new Error('When oneZone is enabled and vpcSubnets defined, vpcSubnets.availabilityZones can not be undefined.'); + throw new ValidationError('When oneZone is enabled and vpcSubnets defined, vpcSubnets.availabilityZones can not be undefined.', this); } // when vpcSubnets.availabilityZones is defined if (this.props.vpcSubnets && this.props.vpcSubnets.availabilityZones) { // it has to be only one az if (this.props.vpcSubnets.availabilityZones?.length !== 1) { - throw new Error('When oneZone is enabled, vpcSubnets.availabilityZones should exactly have one zone.'); + throw new ValidationError('When oneZone is enabled, vpcSubnets.availabilityZones should exactly have one zone.', this); } // it has to be in availabilityZones // but we only check this when vpc.availabilityZones are valid(not dummy values nore unresolved tokens) @@ -906,7 +906,7 @@ export class FileSystem extends FileSystemBase { if (this.props.vpc.availabilityZones.every(isNotUnresolvedToken) && this.props.vpc.availabilityZones.every(isNotDummy) && !this.props.vpc.availabilityZones.includes(this.props.vpcSubnets.availabilityZones[0])) { - throw new Error('vpcSubnets.availabilityZones specified is not in vpc.availabilityZones.'); + throw new ValidationError('vpcSubnets.availabilityZones specified is not in vpc.availabilityZones.', this); } } } @@ -950,7 +950,7 @@ class ImportedFileSystem extends FileSystemBase { addConstructMetadata(this, attrs); if (!!attrs.fileSystemId === !!attrs.fileSystemArn) { - throw new Error('One of fileSystemId or fileSystemArn, but not both, must be provided.'); + throw new ValidationError('One of fileSystemId or fileSystemArn, but not both, must be provided.', this); } this.fileSystemArn = attrs.fileSystemArn ?? Stack.of(scope).formatArn({ @@ -962,7 +962,7 @@ class ImportedFileSystem extends FileSystemBase { const parsedArn = Stack.of(scope).splitArn(this.fileSystemArn, ArnFormat.SLASH_RESOURCE_NAME); if (!parsedArn.resourceName) { - throw new Error(`Invalid FileSystem Arn ${this.fileSystemArn}`); + throw new ValidationError(`Invalid FileSystem Arn ${this.fileSystemArn}`, this); } this.fileSystemId = attrs.fileSystemId ?? parsedArn.resourceName;