From ca92f23aa9f2b92db80fb9421cf12274935623fd Mon Sep 17 00:00:00 2001 From: Amplifiyer <51211245+Amplifiyer@users.noreply.github.com> Date: Mon, 15 Jul 2024 16:00:21 +0200 Subject: [PATCH] wrap yargs validation errors in AmplifyUserError (#1739) * wrap yargs validation errors in AmplifyUserError * PR Updates --- .changeset/lazy-teachers-fold.md | 5 +++ packages/platform-core/API.md | 2 +- .../src/errors/amplify_error.test.ts | 22 ++++++++++ .../platform-core/src/errors/amplify_error.ts | 44 ++++++++++++++++--- 4 files changed, 67 insertions(+), 6 deletions(-) create mode 100644 .changeset/lazy-teachers-fold.md diff --git a/.changeset/lazy-teachers-fold.md b/.changeset/lazy-teachers-fold.md new file mode 100644 index 0000000000..8518e1b90d --- /dev/null +++ b/.changeset/lazy-teachers-fold.md @@ -0,0 +1,5 @@ +--- +'@aws-amplify/platform-core': patch +--- + +wrap yargs validation errors in AmplifyUserError diff --git a/packages/platform-core/API.md b/packages/platform-core/API.md index 79cad2c92f..36e318539b 100644 --- a/packages/platform-core/API.md +++ b/packages/platform-core/API.md @@ -21,7 +21,7 @@ export abstract class AmplifyError extends Error { // (undocumented) readonly details?: string; // (undocumented) - static fromError: (error: unknown) => AmplifyError<'UnknownFault' | 'CredentialsError'>; + static fromError: (error: unknown) => AmplifyError<'UnknownFault' | 'CredentialsError' | 'InvalidCommandInputError'>; // (undocumented) static fromStderr: (_stderr: string) => AmplifyError | undefined; // (undocumented) diff --git a/packages/platform-core/src/errors/amplify_error.test.ts b/packages/platform-core/src/errors/amplify_error.test.ts index 652801e8be..47d31b05d7 100644 --- a/packages/platform-core/src/errors/amplify_error.test.ts +++ b/packages/platform-core/src/errors/amplify_error.test.ts @@ -148,3 +148,25 @@ and some after the error message assert.deepStrictEqual(actual?.resolution, 'test resolution'); }); }); + +void describe('AmplifyError.fromError', async () => { + void it('wraps Yargs validation errors in AmplifyUserError', () => { + const yargsErrors = [ + new Error('Unknown command: asd'), + new Error('Unknown arguments: a,b,c'), + new Error('Missing required argument: d'), + new Error('Did you mean sandbox'), + new Error('Not enough non-option arguments: got 2, need at least 4'), + new Error('Invalid values: Arguments: a, Given: n, Choices: [b, c, d]'), + new Error('Arguments a and b are mutually exclusive'), + ]; + yargsErrors.forEach((error) => { + const actual = AmplifyError.fromError(error); + assert.ok( + actual instanceof AmplifyError && + actual.name === 'InvalidCommandInputError', + `Failed the test for error ${error.message}` + ); + }); + }); +}); diff --git a/packages/platform-core/src/errors/amplify_error.ts b/packages/platform-core/src/errors/amplify_error.ts index 1634bcdbf2..11ad4b483e 100644 --- a/packages/platform-core/src/errors/amplify_error.ts +++ b/packages/platform-core/src/errors/amplify_error.ts @@ -100,17 +100,34 @@ export abstract class AmplifyError extends Error { static fromError = ( error: unknown - ): AmplifyError<'UnknownFault' | 'CredentialsError'> => { + ): AmplifyError< + 'UnknownFault' | 'CredentialsError' | 'InvalidCommandInputError' + > => { const errorMessage = error instanceof Error ? `${error.name}: ${error.message}` : 'An unknown error happened. Check downstream error'; if (error instanceof Error && isCredentialsError(error)) { - return new AmplifyUserError('CredentialsError', { - message: errorMessage, - resolution: '', - }); + return new AmplifyUserError( + 'CredentialsError', + { + message: errorMessage, + resolution: + 'Ensure your AWS credentials are correctly set and refreshed.', + }, + error + ); + } + if (error instanceof Error && isYargsValidationError(error)) { + return new AmplifyUserError( + 'InvalidCommandInputError', + { + message: errorMessage, + resolution: 'Please see the underlying error message for resolution.', + }, + error + ); } return new AmplifyFault( 'UnknownFault', @@ -126,6 +143,23 @@ const isCredentialsError = (err?: Error): boolean => { return !!err && err?.name === 'CredentialsProviderError'; }; +// These validation messages are taken from https://github.com/yargs/yargs/blob/0c95f9c79e1810cf9c8964fbf7d139009412f7e7/lib/validation.ts +const isYargsValidationError = (err?: Error): boolean => { + return ( + !!err && + ([ + 'Unknown command', + 'Unknown argument', + 'Did you mean', + 'Not enough non-option arguments', + 'Too many non-option arguments', + 'Missing required argument', + 'Invalid values:', + ].some((message) => err.message.startsWith(message)) || + err.message.endsWith('are mutually exclusive')) + ); +}; + /** * Amplify exception classifications */