Skip to content

Commit 583a3f2

Browse files
authored
Fix detection of AmplifyErrors (#2200)
* Fix detection of AmplifyErrors * fix check * fix check
1 parent 1af5060 commit 583a3f2

File tree

14 files changed

+117
-12
lines changed

14 files changed

+117
-12
lines changed

.changeset/green-cups-jam.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@aws-amplify/platform-core': minor
3+
'@aws-amplify/backend-deployer': patch
4+
'@aws-amplify/backend-data': patch
5+
'@aws-amplify/backend': patch
6+
'@aws-amplify/sandbox': patch
7+
'@aws-amplify/backend-cli': patch
8+
---
9+
10+
Fix detection of AmplifyErrors

.eslint_dictionary.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
"idps",
8282
"implementors",
8383
"inheritdoc",
84+
"instanceof",
8485
"interop",
8586
"invokable",
8687
"invoker",

packages/backend-data/src/factory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ class DataGenerator implements ConstructContainerEntryGenerator {
184184
this.props.authorizationModes
185185
);
186186
} catch (error) {
187-
if (error instanceof AmplifyError) {
187+
if (AmplifyError.isAmplifyError(error)) {
188188
throw error;
189189
}
190190
throw new AmplifyUserError<AmplifyDataError>(

packages/backend-deployer/src/cdk_deployer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export class CDKDeployer implements BackendDeployer {
8686
} catch (typeError: unknown) {
8787
if (
8888
synthError &&
89-
typeError instanceof AmplifyError &&
89+
AmplifyError.isAmplifyError(typeError) &&
9090
typeError.cause?.message.match(
9191
/Cannot find module '\$amplify\/env\/.*' or its corresponding type declarations/
9292
)

packages/cli/src/commands/sandbox/sandbox_command.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ void describe('sandbox command', () => {
121121
() =>
122122
commandRunner.runCommand(`sandbox --identifier ${invalidIdentifier}`), // invalid identifier
123123
(err: TestCommandError) => {
124-
assert.ok(err.error instanceof AmplifyError);
124+
assert.ok(AmplifyError.isAmplifyError(err.error));
125125
assert.strictEqual(
126126
err.error.message,
127127
'Invalid --identifier provided: invalid@'

packages/cli/src/commands/sandbox/sandbox_event_handler_factory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export class SandboxEventHandlerFactory {
6464
return;
6565
}
6666
const deployError = args[0];
67-
if (deployError && deployError instanceof AmplifyError) {
67+
if (deployError && AmplifyError.isAmplifyError(deployError)) {
6868
await usageDataEmitter.emitFailure(deployError, {
6969
command: 'Sandbox',
7070
});

packages/cli/src/error_handler.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ const handleError = async ({
111111

112112
printMessagePreamble?.();
113113

114-
if (error instanceof AmplifyError) {
114+
if (AmplifyError.isAmplifyError(error)) {
115115
printer.print(format.error(`${error.name}: ${error.message}`));
116116

117117
if (error.resolution) {
@@ -141,7 +141,7 @@ const handleError = async ({
141141
}
142142

143143
await usageDataEmitter?.emitFailure(
144-
error instanceof AmplifyError
144+
AmplifyError.isAmplifyError(error)
145145
? error
146146
: AmplifyError.fromError(
147147
error && error instanceof Error ? error : new Error(message)

packages/eslint-rules/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ import { noEmptyCatchRule } from './rules/no_empty_catch.js';
22
import { amplifyErrorNameRule } from './rules/amplify_error_name.js';
33
import { preferAmplifyErrorsRule } from './rules/prefer_amplify_errors.js';
44
import { noAmplifyErrors } from './rules/no_amplify_errors.js';
5+
import { amplifyErrorNoInstanceOf } from './rules/amplify_error_no_instance_of';
56

67
export const rules: Record<string, unknown> = {
78
'amplify-error-name': amplifyErrorNameRule,
9+
'amplify-error-no-instanceof': amplifyErrorNoInstanceOf,
810
'no-empty-catch': noEmptyCatchRule,
911
'prefer-amplify-errors': preferAmplifyErrorsRule,
1012
'no-amplify-errors': noAmplifyErrors,
@@ -15,6 +17,7 @@ export const configs = {
1517
plugins: ['amplify-backend-rules'],
1618
rules: {
1719
'amplify-backend-rules/amplify-error-name': 'error',
20+
'amplify-backend-rules/amplify-error-no-instanceof': 'error',
1821
'amplify-backend-rules/no-empty-catch': 'error',
1922
'amplify-backend-rules/prefer-amplify-errors': 'off',
2023
'amplify-backend-rules/no-amplify-errors': 'off',
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import * as nodeTest from 'node:test';
2+
import { RuleTester } from '@typescript-eslint/rule-tester';
3+
import { amplifyErrorNoInstanceOf } from './amplify_error_no_instance_of.js';
4+
5+
RuleTester.afterAll = nodeTest.after;
6+
// See https://typescript-eslint.io/packages/rule-tester/#with-specific-frameworks
7+
// Node test runner methods return promises which are not relevant in the context of testing.
8+
// We do ignore them in other places with void keyword.
9+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
10+
RuleTester.it = nodeTest.it;
11+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
12+
RuleTester.describe = nodeTest.describe;
13+
14+
const ruleTester = new RuleTester();
15+
16+
ruleTester.run('amplify-error-no-instanceof', amplifyErrorNoInstanceOf, {
17+
valid: ['e instanceof Error'],
18+
invalid: [
19+
{
20+
code: 'e instanceof AmplifyError',
21+
errors: [
22+
{
23+
messageId: 'noInstanceOfWithAmplifyError',
24+
},
25+
],
26+
},
27+
],
28+
});
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { ESLintUtils } from '@typescript-eslint/utils';
2+
3+
/**
4+
* This rule flags empty catch blocks. Even if they contain comments.
5+
*
6+
* This rule differs from built in https://github.com/eslint/eslint/blob/main/lib/rules/no-empty.js
7+
* in such a way that it uses typescript-eslint and typescript AST
8+
* which does not include comments as statements in catch clause body block.
9+
*/
10+
export const amplifyErrorNoInstanceOf = ESLintUtils.RuleCreator.withoutDocs({
11+
create(context) {
12+
return {
13+
// This naming comes from @typescript-eslint/utils types.
14+
// eslint-disable-next-line @typescript-eslint/naming-convention
15+
BinaryExpression(node) {
16+
if (
17+
node.operator === 'instanceof' &&
18+
node.right.type === 'Identifier' &&
19+
node.right.name === 'AmplifyError'
20+
) {
21+
context.report({
22+
messageId: 'noInstanceOfWithAmplifyError',
23+
node,
24+
});
25+
}
26+
},
27+
};
28+
},
29+
meta: {
30+
docs: {
31+
description: 'Instanceof operator must not be used with AmplifyError.',
32+
},
33+
messages: {
34+
noInstanceOfWithAmplifyError:
35+
'Do not use instanceof with AmplifyError. Use AmplifyError.isAmplifyError instead.',
36+
},
37+
type: 'problem',
38+
schema: [],
39+
},
40+
defaultOptions: [],
41+
});

0 commit comments

Comments
 (0)