Skip to content

Commit ba2f5c8

Browse files
authored
feat(appmesh): throw ValidationError istead of untyped Errors (#33245)
### Issue `aws-appmesh` for #32569 ### Description of changes ValidationErrors everywhere ### Describe any new or updated permissions being added n/a ### Description of how you validated changes Existing tests. Exemptions granted as this is basically a refactor of existing code. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 2e7c3e8 commit ba2f5c8

File tree

9 files changed

+37
-34
lines changed

9 files changed

+37
-34
lines changed

packages/aws-cdk-lib/.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ const enableNoThrowDefaultErrorIn = [
2424
'aws-apigatewayv2-integrations',
2525
'aws-applicationautoscaling',
2626
'aws-appsync',
27+
'aws-appmesh',
2728
'aws-cognito',
2829
'aws-elasticloadbalancing',
2930
'aws-elasticloadbalancingv2',

packages/aws-cdk-lib/aws-appmesh/lib/gateway-route-spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@ class GrpcGatewayRouteSpec extends GatewayRouteSpec {
364364
public bind(scope: Construct): GatewayRouteSpecConfig {
365365
const metadataMatch = this.match.metadata;
366366

367-
validateGrpcGatewayRouteMatch(this.match);
368-
validateGrpcMatchArrayLength(metadataMatch);
367+
validateGrpcGatewayRouteMatch(scope, this.match);
368+
validateGrpcMatchArrayLength(scope, metadataMatch);
369369

370370
return {
371371
grpcSpecConfig: {

packages/aws-cdk-lib/aws-appmesh/lib/health-checks.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,19 +138,19 @@ class HealthCheckImpl extends HealthCheck {
138138
private readonly path?: string) {
139139
super();
140140
if (healthyThreshold < 2 || healthyThreshold > 10) {
141-
throw new Error('healthyThreshold must be between 2 and 10');
141+
throw new cdk.UnscopedValidationError('healthyThreshold must be between 2 and 10');
142142
}
143143

144144
if (unhealthyThreshold < 2 || unhealthyThreshold > 10) {
145-
throw new Error('unhealthyThreshold must be between 2 and 10');
145+
throw new cdk.UnscopedValidationError('unhealthyThreshold must be between 2 and 10');
146146
}
147147

148148
if (interval.toMilliseconds() < 5000 || interval.toMilliseconds() > 300_000) {
149-
throw new Error('interval must be between 5 seconds and 300 seconds');
149+
throw new cdk.UnscopedValidationError('interval must be between 5 seconds and 300 seconds');
150150
}
151151

152152
if (timeout.toMilliseconds() < 2000 || timeout.toMilliseconds() > 60_000) {
153-
throw new Error('timeout must be between 2 seconds and 60 seconds');
153+
throw new cdk.UnscopedValidationError('timeout must be between 2 seconds and 60 seconds');
154154
}
155155

156156
// Default to / for HTTP Health Checks

packages/aws-cdk-lib/aws-appmesh/lib/http-route-path-match.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Construct } from 'constructs';
22
import { CfnGatewayRoute, CfnRoute } from './appmesh.generated';
3+
import { UnscopedValidationError } from '../../core/lib/errors';
34

45
/**
56
* The type returned from the `bind()` method in `HttpRoutePathMatch`.
@@ -66,7 +67,7 @@ class HttpRoutePrefixPathMatch extends HttpRoutePathMatch {
6667
super();
6768

6869
if (prefix && prefix[0] !== '/') {
69-
throw new Error(`Prefix Path for the match must start with \'/\', got: ${prefix}`);
70+
throw new UnscopedValidationError(`Prefix Path for the match must start with \'/\', got: ${prefix}`);
7071
}
7172
}
7273

@@ -82,7 +83,7 @@ class HttpRouteWholePathMatch extends HttpRoutePathMatch {
8283
super();
8384

8485
if (match.exact && match.exact[0] !== '/') {
85-
throw new Error(`Exact Path for the match must start with \'/\', got: ${match.exact}`);
86+
throw new UnscopedValidationError(`Exact Path for the match must start with \'/\', got: ${match.exact}`);
8687
}
8788
}
8889

@@ -184,17 +185,17 @@ class HttpGatewayRoutePrefixPathMatch extends HttpGatewayRoutePathMatch {
184185
super();
185186

186187
if (prefixPathMatch[0] !== '/') {
187-
throw new Error('Prefix path for the match must start with \'/\', '
188+
throw new UnscopedValidationError('Prefix path for the match must start with \'/\', '
188189
+ `got: ${prefixPathMatch}`);
189190
}
190191

191192
if (rewriteTo) {
192193
if (prefixPathMatch[prefixPathMatch.length - 1] !== '/') {
193-
throw new Error('When prefix path for the rewrite is specified, prefix path for the match must end with \'/\', '
194+
throw new UnscopedValidationError('When prefix path for the rewrite is specified, prefix path for the match must end with \'/\', '
194195
+ `got: ${prefixPathMatch}`);
195196
}
196197
if (rewriteTo[0] !== '/' || rewriteTo[rewriteTo.length - 1] !== '/') {
197-
throw new Error('Prefix path for the rewrite must start and end with \'/\', '
198+
throw new UnscopedValidationError('Prefix path for the rewrite must start and end with \'/\', '
198199
+ `got: ${rewriteTo}`);
199200
}
200201
}
@@ -221,13 +222,13 @@ class HttpGatewayRouteWholePathMatch extends HttpGatewayRoutePathMatch {
221222
super();
222223

223224
if (wholePathMatch.exact && wholePathMatch.exact[0] !== '/') {
224-
throw new Error(`Exact Path for the match must start with \'/\', got: ${ wholePathMatch.exact }`);
225+
throw new UnscopedValidationError(`Exact Path for the match must start with \'/\', got: ${ wholePathMatch.exact }`);
225226
}
226227
if (exactPathRewrite === '') {
227-
throw new Error('Exact Path for the rewrite cannot be empty. Unlike startsWith() method, no automatic rewrite on whole path match');
228+
throw new UnscopedValidationError('Exact Path for the rewrite cannot be empty. Unlike startsWith() method, no automatic rewrite on whole path match');
228229
}
229230
if (exactPathRewrite && exactPathRewrite[0] !== '/') {
230-
throw new Error(`Exact Path for the rewrite must start with \'/\', got: ${ exactPathRewrite }`);
231+
throw new UnscopedValidationError(`Exact Path for the rewrite must start with \'/\', got: ${ exactPathRewrite }`);
231232
}
232233
}
233234

packages/aws-cdk-lib/aws-appmesh/lib/private/utils.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Construct } from 'constructs';
2-
import { Token, TokenComparison } from '../../../core';
2+
import { Token, TokenComparison, ValidationError } from '../../../core';
33
import { CfnVirtualNode } from '../appmesh.generated';
44
import { GrpcGatewayRouteMatch } from '../gateway-route-spec';
55
import { HeaderMatch } from '../header-match';
@@ -97,45 +97,45 @@ export function renderMeshOwner(resourceAccount: string, meshAccount: string) :
9797
/**
9898
* This is the helper method to validate the length of HTTP match array when it is specified.
9999
*/
100-
export function validateHttpMatchArrayLength(headers?: HeaderMatch[], queryParameters?: QueryParameterMatch[]) {
100+
export function validateHttpMatchArrayLength(scope: Construct, headers?: HeaderMatch[], queryParameters?: QueryParameterMatch[]) {
101101
const MIN_LENGTH = 1;
102102
const MAX_LENGTH = 10;
103103

104104
if (headers && (headers.length < MIN_LENGTH || headers.length > MAX_LENGTH)) {
105-
throw new Error(`Number of headers provided for matching must be between ${MIN_LENGTH} and ${MAX_LENGTH}, got: ${headers.length}`);
105+
throw new ValidationError(`Number of headers provided for matching must be between ${MIN_LENGTH} and ${MAX_LENGTH}, got: ${headers.length}`, scope);
106106
}
107107

108108
if (queryParameters && (queryParameters.length < MIN_LENGTH || queryParameters.length > MAX_LENGTH)) {
109-
throw new Error(`Number of query parameters provided for matching must be between ${MIN_LENGTH} and ${MAX_LENGTH}, got: ${queryParameters.length}`);
109+
throw new ValidationError(`Number of query parameters provided for matching must be between ${MIN_LENGTH} and ${MAX_LENGTH}, got: ${queryParameters.length}`, scope);
110110
}
111111
}
112112

113113
/**
114114
* This is the helper method to validate the length of gRPC match array when it is specified.
115115
*/
116-
export function validateGrpcMatchArrayLength(metadata?: HeaderMatch[]): void {
116+
export function validateGrpcMatchArrayLength(scope: Construct, metadata?: HeaderMatch[]): void {
117117
const MIN_LENGTH = 1;
118118
const MAX_LENGTH = 10;
119119

120120
if (metadata && (metadata.length < MIN_LENGTH || metadata.length > MAX_LENGTH)) {
121-
throw new Error(`Number of metadata provided for matching must be between ${MIN_LENGTH} and ${MAX_LENGTH}, got: ${metadata.length}`);
121+
throw new ValidationError(`Number of metadata provided for matching must be between ${MIN_LENGTH} and ${MAX_LENGTH}, got: ${metadata.length}`, scope);
122122
}
123123
}
124124

125125
/**
126126
* This is the helper method to validate at least one of gRPC route match type is defined.
127127
*/
128-
export function validateGrpcRouteMatch(match: GrpcRouteMatch): void {
128+
export function validateGrpcRouteMatch(scope: Construct, match: GrpcRouteMatch): void {
129129
if (match.serviceName === undefined && match.metadata === undefined && match.methodName === undefined && match.port === undefined) {
130-
throw new Error('At least one gRPC route match property must be provided');
130+
throw new ValidationError('At least one gRPC route match property must be provided', scope);
131131
}
132132
}
133133

134134
/**
135135
* This is the helper method to validate at least one of gRPC gateway route match type is defined.
136136
*/
137-
export function validateGrpcGatewayRouteMatch(match: GrpcGatewayRouteMatch): void {
137+
export function validateGrpcGatewayRouteMatch(scope: Construct, match: GrpcGatewayRouteMatch): void {
138138
if (match.serviceName === undefined && match.metadata === undefined && match.hostname === undefined && match.port === undefined) {
139-
throw new Error('At least one gRPC gateway route match property beside rewriteRequestHostname must be provided');
139+
throw new ValidationError('At least one gRPC gateway route match property beside rewriteRequestHostname must be provided', scope);
140140
}
141141
}

packages/aws-cdk-lib/aws-appmesh/lib/route-spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -449,7 +449,7 @@ class HttpRouteSpec extends RouteSpec {
449449
const tcpRetryEvents = props.retryPolicy.tcpRetryEvents ?? [];
450450

451451
if (httpRetryEvents.length + tcpRetryEvents.length === 0) {
452-
throw new Error('You must specify one value for at least one of `httpRetryEvents` or `tcpRetryEvents`');
452+
throw new cdk.UnscopedValidationError('You must specify one value for at least one of `httpRetryEvents` or `tcpRetryEvents`');
453453
}
454454

455455
this.retryPolicy = {
@@ -467,7 +467,7 @@ class HttpRouteSpec extends RouteSpec {
467467
const headers = this.match?.headers;
468468
const queryParameters = this.match?.queryParameters;
469469

470-
validateHttpMatchArrayLength(headers, queryParameters);
470+
validateHttpMatchArrayLength(scope, headers, queryParameters);
471471

472472
const httpConfig: CfnRoute.HttpRouteProperty = {
473473
action: {
@@ -557,7 +557,7 @@ class GrpcRouteSpec extends RouteSpec {
557557
const tcpRetryEvents = props.retryPolicy.tcpRetryEvents ?? [];
558558

559559
if (grpcRetryEvents.length + httpRetryEvents.length + tcpRetryEvents.length === 0) {
560-
throw new Error('You must specify one value for at least one of `grpcRetryEvents`, `httpRetryEvents` or `tcpRetryEvents`');
560+
throw new cdk.UnscopedValidationError('You must specify one value for at least one of `grpcRetryEvents`, `httpRetryEvents` or `tcpRetryEvents`');
561561
}
562562

563563
this.retryPolicy = {
@@ -575,11 +575,11 @@ class GrpcRouteSpec extends RouteSpec {
575575
const metadata = this.match.metadata;
576576
const port = this.match.port;
577577

578-
validateGrpcRouteMatch(this.match);
579-
validateGrpcMatchArrayLength(metadata);
578+
validateGrpcRouteMatch(scope, this.match);
579+
validateGrpcMatchArrayLength(scope, metadata);
580580

581581
if (methodName && !serviceName) {
582-
throw new Error('If you specify a method name, you must also specify a service name');
582+
throw new cdk.ValidationError('If you specify a method name, you must also specify a service name', scope);
583583
}
584584

585585
return {

packages/aws-cdk-lib/aws-appmesh/lib/shared-interfaces.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ export abstract class LoggingFormat {
199199
*/
200200
public static fromJson(jsonLoggingFormat :{[key:string]: string}): LoggingFormat {
201201
if (Object.keys(jsonLoggingFormat).length == 0) {
202-
throw new Error('Json key pairs cannot be empty.');
202+
throw new cdk.UnscopedValidationError('Json key pairs cannot be empty.');
203203
}
204204

205205
return new JsonLoggingFormat(jsonLoggingFormat);

packages/aws-cdk-lib/aws-appmesh/lib/tls-validation.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Construct } from 'constructs';
22
import { CfnVirtualNode } from './appmesh.generated';
33
import * as acmpca from '../../aws-acmpca';
4+
import { ValidationError } from '../../core/lib/errors';
45

56
/**
67
* Represents the properties needed to define TLS Validation context
@@ -98,9 +99,9 @@ class TlsValidationAcmTrust extends TlsValidationTrust {
9899
this.certificateAuthorities = certificateAuthorities;
99100
}
100101

101-
public bind(_scope: Construct): TlsValidationTrustConfig {
102+
public bind(scope: Construct): TlsValidationTrustConfig {
102103
if (this.certificateAuthorities.length === 0) {
103-
throw new Error('you must provide at least one Certificate Authority when creating an ACM Trust ClientPolicy');
104+
throw new ValidationError('you must provide at least one Certificate Authority when creating an ACM Trust ClientPolicy', scope);
104105
} else {
105106
return {
106107
tlsValidationTrust: {

packages/aws-cdk-lib/aws-appmesh/lib/virtual-node.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ export class VirtualNode extends VirtualNodeBase {
233233
*/
234234
public addListener(listener: VirtualNodeListener) {
235235
if (!this.serviceDiscoveryConfig) {
236-
throw new Error('Service discovery information is required for a VirtualNode with a listener.');
236+
throw new cdk.ValidationError('Service discovery information is required for a VirtualNode with a listener.', this);
237237
}
238238
this.listeners.push(listener.bind(this));
239239
}

0 commit comments

Comments
 (0)