Skip to content

Commit 7032872

Browse files
authored
docs: update guidance on instanceof Exception checking (#7351)
1 parent 79bbaf4 commit 7032872

File tree

1 file changed

+52
-31
lines changed

1 file changed

+52
-31
lines changed

supplemental-docs/ERROR_HANDLING.md

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,33 @@ The most common compilation error related to this SDK is the following:
1111
'A' is assignable to the constraint of type 'B', but 'B' could be instantiated with a different subtype of constraint 'C'.
1212
```
1313

14-
This is due to `node_modules` nesting and duplication when handling transitive dependencies that exist at multiple different versions within a single workspace.
15-
Most commonly, this is caused by an application installing different versions of various SDK clients that all depend on `@smithy/types` or `@aws-sdk/types`, but at different versions.
14+
This is due to `node_modules` nesting and duplication when handling transitive dependencies that exist at multiple
15+
different versions within a single workspace.
16+
Most commonly, this is caused by an application installing different versions of various SDK clients that all depend on
17+
`@smithy/types` or `@aws-sdk/types`, but at different versions.
1618

17-
To remedy this, install every `@aws-sdk/client-*` package at or around the same version.
19+
To remedy this, install every `@aws-sdk/client-*` package at or around the same version.
1820

1921
```json
2022
{
2123
"name": "your-app",
2224
"dependencies": {
23-
"@aws-sdk/client-s3": "<=3.600.0",
24-
"@aws-sdk/client-dynamodb": "<=3.600.0",
25-
"@aws-sdk/client-lambda": "<=3.600.0",
25+
"@aws-sdk/client-s3": "<=3.800.0",
26+
"@aws-sdk/client-dynamodb": "<=3.800.0",
27+
"@aws-sdk/client-lambda": "<=3.800.0"
2628
}
2729
}
2830
```
2931

30-
The `<=` version prefix means to install the greatest version number below or at the given value. This is helpful because the `@aws-sdk/*` namespace
31-
only releases package version updates when there are changes, but the version number in the monorepo increments every day. Not every minor version number exists for each package.
32+
The `<=` version prefix means to install the greatest version number below or at the given value. This is helpful
33+
because the `@aws-sdk/*` namespace
34+
only releases package version updates when there are changes, but the version number in the monorepo increments every
35+
day. Not every minor version number exists for each package.
3236

3337
## Runtime errors not related to AWS service responses
3438

35-
You may encounter SDK errors before a request is made. Since we provide a TypeScript API, we do not runtime typecheck every value, since that would increase application size.
39+
You may encounter SDK errors before a request is made. Since we provide a TypeScript API, we do not runtime typecheck
40+
every value, since that would increase application size.
3641

3742
```ts
3843
// Example runtime error prior to request
@@ -43,36 +48,45 @@ const s3 = new S3();
4348
await s3.getObject({
4449
Bucket: "my-bucket",
4550
Key: 5 as any, // since this should be a string, the resulting error is thrown even prior to the request being sent.
46-
// TypeError: labelValue.split is not a function
51+
// TypeError: labelValue.split is not a function
4752
});
4853
```
4954

50-
In such cases, refer to the API documentation or TypeScript declarations, or create an [issue report](https://github.com/aws/aws-sdk-js-v3/issues) for additional assistance.
55+
In such cases, refer to the API documentation or TypeScript declarations, or create
56+
an [issue report](https://github.com/aws/aws-sdk-js-v3/issues) for additional assistance.
5157

5258
## Errors returned by AWS services
5359

54-
Non-2xx responses from AWS services are surfaced to the user as thrown JavaScript `Error`s.
60+
Non-2xx responses from AWS services are surfaced to the user as thrown JavaScript `Error`s.
61+
62+
Since this SDK is generated from Smithy models, there is a conceptual notion of "unmodeled" and "modeled" errors.
5563

56-
Since this SDK is generated from Smithy models, there is a conceptual notion of "unmodeled" and "modeled" errors.
5764
- A modeled error or exception is an error that is declared by the service model. For example, at the bottom of the page
58-
https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/lambda/command/CreateFunctionCommand/, there is a list of named
59-
exceptions. These are the modeled exceptions for this Command or operation.
60-
- An unmodeled error is one that does not appear in the list, but is thrown at runtime by the service. Some errors are unmodeled
61-
because of incomplete modeling by the service, or because of routing layers, load balancers, security etc. that sit in front
62-
of the service.
63-
64-
Unmodeled errors are created as the default ServiceException class that exists for each AWS service, which the modeled errors also extend.
65-
In the AWS Lambda example, it is the one at the bottom that reads:
65+
https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/lambda/command/CreateFunctionCommand/, there is a list
66+
of named exceptions. These are the modeled exceptions for this Command or operation.
67+
- An unmodeled error is one that does not appear in the list, but is thrown at runtime by the service. Some errors are
68+
unmodeled because of incomplete modeling by the service, or because of routing layers, load balancers, security etc.
69+
that sit in front of the service.
70+
71+
Unmodeled errors are created as the default ServiceException class that exists for each AWS service, which the modeled
72+
errors also extend. In the AWS Lambda example, it is the one at the bottom that reads:
73+
6674
```
6775
LambdaServiceException - Base exception class for all service exceptions from Lambda service.
6876
```
6977

7078
### Handling service returned errors
7179

7280
As seen in the example below, SDK error handling best-practices involve the following points:
73-
- cast the initial unknown error to the service base exception type to have type-access to the `$metadata` and `$response` fields.
81+
82+
- cast the initial unknown error to the service base exception type to have type-access to the `$metadata` and
83+
`$response` fields.
7484
- you can use switches to handle errors based on
75-
- the error name. `instanceof` checks are not recommended for error handling due to the possibility of prototype mismatch caused by nesting or other forms of copying/duplication.
85+
- the error name.
86+
- error class `instanceof` operator calls.
87+
- Although `instanceof` calls are in general somewhat dangerous across different packages due to NPM's module
88+
nesting feature, the base `ServiceException` type in the AWS SDK has a `[Symbol.hasInstance]` method override, and
89+
should work just as well as comparing by `name` property.
7690
- the `$metadata.httpStatusCode` value.
7791
- additional fields on the raw HTTP response object available at `error.$response`.
7892

@@ -98,16 +112,19 @@ try {
98112
// checking the name of the error.
99113
switch (e.name) {
100114
case CodeStorageExceededException.name:
101-
break;
102115
case TooManyRequestsException.name:
103-
break;
104116
case LambdaServiceException.name:
105117
default:
106-
break;
107118
}
108119

109120
// checking the response status code.
110121
switch (e.$metadata.httpStatusCode) {
122+
case 500:
123+
case 404:
124+
case 403:
125+
case 400:
126+
case 200:
127+
default:
111128
}
112129

113130
// checking additional fields of
@@ -124,14 +141,19 @@ try {
124141

125142
### Parsing errors arising from service responses
126143

127-
An additional untyped field may be present, called `error.$responseBodyText`. This is only populated when the SDK fails to parse the error response, because
128-
it is in an unexpected format. For example, if the service model says the service data format is JSON, but the error body is plaintext.
129-
This can happen if for example a front-end layer throttles the request but is unaware of the underlying service data format.
144+
An additional untyped field may be present, called `error.$responseBodyText`. This is only
145+
populated when the SDK fails to parse the error response, because it is in an unexpected format. For example, if the
146+
service model says the service data format is JSON, but the error body is plaintext.
147+
This can happen if for example a front-end layer throttles the request but is unaware of the underlying service data
148+
format.
130149

131150
In such cases, the error message will include the hint
151+
132152
```
133-
Deserialization error: to see the raw response, inspect the hidden field {error}.$response on this object.
153+
Deserialization error: to see the raw response, inspect the
154+
hidden field {error}.$response on this object.
134155
```
156+
135157
It is not automatically logged to avoid accidental logging of sensitive data.
136158

137159
To inspect it:
@@ -150,4 +172,3 @@ try {
150172
}
151173
}
152174
```
153-

0 commit comments

Comments
 (0)