Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add error mapping for Amplify app not found in specified region #2313

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/ninety-coins-jog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@aws-amplify/backend-cli': patch
---

Added error mapping for app name not available in the region
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
GenerateModelsOptions,
} from '@aws-amplify/model-generator';
import { ArgumentsKebabCase } from '../../../kebab_case.js';
import { AmplifyUserError } from '@aws-amplify/platform-core';

type GenerateOptions =
| GenerateGraphqlCodegenOptions
Expand Down Expand Up @@ -89,20 +90,36 @@ export class GenerateGraphqlClientCodeCommand
handler = async (
args: ArgumentsCamelCase<GenerateGraphqlClientCodeCommandOptions>
): Promise<void> => {
const backendIdentifier =
await this.backendIdentifierResolver.resolveDeployedBackendIdentifier(
args
);
const out = this.getOutDir(args);
const format = args.format ?? GenerateApiCodeFormat.GRAPHQL_CODEGEN;
const formatParams = this.formatParamBuilders[format](args);
try {
const backendIdentifier =
await this.backendIdentifierResolver.resolveDeployedBackendIdentifier(
args
);
const out = this.getOutDir(args);
const format = args.format ?? GenerateApiCodeFormat.GRAPHQL_CODEGEN;
const formatParams = this.formatParamBuilders[format](args);

const result = await this.generateApiCodeAdapter.invokeGenerateApiCode({
...backendIdentifier,
...formatParams,
} as unknown as InvokeGenerateApiCodeProps);

const result = await this.generateApiCodeAdapter.invokeGenerateApiCode({
...backendIdentifier,
...formatParams,
} as unknown as InvokeGenerateApiCodeProps);
await result.writeToDirectory(out);
} catch (error) {
const appNotFoundMatch = (error as Error).message.match(
/No apps found with name (?<appName>.*) in region (?<region>.*)/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of regex matching, we should update the error thrown to have contextual information. E.g. see this example here in the deployed-backend-client package

export enum BackendOutputClientErrorType {
METADATA_RETRIEVAL_ERROR = 'MetadataRetrievalError',
NO_OUTPUTS_FOUND = 'NoOutputsFound',
DEPLOYMENT_IN_PROGRESS = 'DeploymentInProgress',
NO_STACK_FOUND = 'NoStackFound',
CREDENTIALS_ERROR = 'CredentialsError',
ACCESS_DENIED = 'AccessDenied',
}
/**
* Error type for BackendOutputClientError
*/
export class BackendOutputClientError extends Error {
public code: BackendOutputClientErrorType;
and usage here 3cf0738#diff-6575515384ffad97860f57f5a6eea59fb54b2813c72d8c610b7c7a8c5cc29258

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

);

await result.writeToDirectory(out);
if (appNotFoundMatch?.groups) {
const { appName, region } = appNotFoundMatch.groups;
throw new AmplifyUserError('AmplifyAppNotFoundError', {
message: `No Amplify app found with name "${appName}" in region "${region}".`,
resolution: `Ensure that an Amplify app named "${appName}" exists in the "${region}" region.`,
});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My question is still not answered. How are you able to reproduce this and validate it? I don't see appName as a user input anywhere so not sure how this can be easily categorized as a User Error.
What situation(s) can lead to this error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have moved the try-catch wrapper to a common resolver where all the generate command finally lands.I have updated the repro steps in the description. Seems to be happening only if the --branch option is set without the AppID

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is mostly happening in the console (based on the isCI flag in the telemetry) where customers might not be explicitly providing these values and the region should match if customers are using the Amplify Console to download the output file.

Seems to be happening only if the --branch option is set without the AppID

Yes, when only --branch is set, the appName is loaded from the Amplify Service and filtered on the appName which is coming from the packageJson#Name (I think).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is mostly happening in the console (based on the isCI flag in the telemetry) where customers might not be explicitly providing these values and the region should match if customers are using the Amplify Console to download the output file.

Input Command CI Percentage Non-CI Percentage
UnknownCommand 31.03 68.97
generate graphql-client-code 0 100
generate outputs 56.33 43.67

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its a valid concern, since appName is internally derived. When I tested out in the right region it works every time. When I'm working in the wrong region it fails. So we can safely call it as UserError.
This condition is triggered only when --branch is used with wrong region

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you tested this in the Console? I understand you can reproduce this in the CLI, but the fact that this issue happens in CI points to the issue could be something else.

Copy link
Contributor Author

@vigy02 vigy02 Dec 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I was able to repro this issue on the console side. I edited the amplify.yml and added wrong build command which caused this issue. The changes that I have implemented in the cli package will be able to handle this.
Screenshot 2024-12-11 at 3 42 44 PM

// Re-throw other errors
throw error;
}
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,25 +55,41 @@ export class GenerateOutputsCommand
handler = async (
args: ArgumentsCamelCase<GenerateOutputsCommandOptions>
): Promise<void> => {
const backendIdentifier =
await this.backendIdentifierResolver.resolveDeployedBackendIdentifier(
args
try {
const backendIdentifier =
await this.backendIdentifierResolver.resolveDeployedBackendIdentifier(
args
);

if (!backendIdentifier) {
throw new AmplifyUserError('BackendIdentifierResolverError', {
message: 'Could not resolve the backend identifier.',
resolution:
'Ensure stack name or Amplify App ID and branch specified are correct and exists, then re-run this command.',
});
}

await this.clientConfigGenerator.generateClientConfigToFile(
backendIdentifier,
args.outputsVersion as ClientConfigVersion,
args.outDir,
args.format
);
} catch (error) {
const appNotFoundMatch = (error as Error).message.match(
/No apps found with name (?<appName>.*) in region (?<region>.*)/
);

if (!backendIdentifier) {
throw new AmplifyUserError('BackendIdentifierResolverError', {
message: 'Could not resolve the backend identifier.',
resolution:
'Ensure stack name or Amplify App ID and branch specified are correct and exists, then re-run this command.',
});
if (appNotFoundMatch?.groups) {
const { appName, region } = appNotFoundMatch.groups;
throw new AmplifyUserError('AmplifyAppNotFoundError', {
message: `No Amplify app found with name "${appName}" in region "${region}".`,
resolution: `Ensure that an Amplify app named "${appName}" exists in the "${region}" region.`,
});
}
// Re-throw other errors
throw error;
}

await this.clientConfigGenerator.generateClientConfigToFile(
backendIdentifier,
args.outputsVersion as ClientConfigVersion,
args.outDir,
args.format
);
};

/**
Expand Down
Loading