Skip to content

Convert some codegen exceptions to ModelInvalidException #6274

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

Merged
merged 3 commits into from
Jul 18, 2025
Merged
Show file tree
Hide file tree
Changes from 2 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
6 changes: 6 additions & 0 deletions .changes/next-release/feature-AWSSDKforJavav2-838b5da.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "feature",
"category": "AWS SDK for Java v2",
"contributor": "",
"description": "Convert codegen exceptions caused by bad customization config or invalid models to ModelInvalidException."
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,12 @@
import software.amazon.awssdk.codegen.model.intermediate.Metadata;
import software.amazon.awssdk.codegen.model.service.ServiceModel;
import software.amazon.awssdk.codegen.model.service.Shape;
import software.amazon.awssdk.codegen.validation.ModelInvalidException;
import software.amazon.awssdk.codegen.validation.ValidationEntry;
import software.amazon.awssdk.codegen.validation.ValidationErrorId;
import software.amazon.awssdk.codegen.validation.ValidationErrorSeverity;
import software.amazon.awssdk.utils.Logger;
import software.amazon.awssdk.utils.StringUtils;
import software.amazon.awssdk.utils.Validate;

/**
* Default implementation of naming strategy respecting.
Expand Down Expand Up @@ -498,17 +501,36 @@ private void validateCustomerVisibleName(String name, String location) {
UnderscoresInNameBehavior behavior = customizationConfig.getUnderscoresInNameBehavior();

String supportedBehaviors = Arrays.toString(UnderscoresInNameBehavior.values());
Validate.notNull(behavior,
"Encountered a name or identifier that the customer will see (%s in the %s) with an underscore. "
+ "This isn't idiomatic in Java. Please either remove the underscores or apply the "
+ "'underscoresInNameBehavior' customization for this service (Supported "
+ "'underscoresInNameBehavior' values: %s).", name, location, supportedBehaviors);
Validate.isTrue(behavior == UnderscoresInNameBehavior.ALLOW,
"Unsupported underscoresInShapeNameBehavior: %s. Supported values: %s", behavior, supportedBehaviors);
if (behavior == null) {
throw ModelInvalidException.fromEntry(ValidationEntry.create(
ValidationErrorId.INVALID_IDENTIFIER_NAME,
ValidationErrorSeverity.DANGER,
String.format(
"Encountered a name or identifier that the customer will see (%s in the %s) with an underscore. "
+ "This isn't idiomatic in Java. Please either remove the underscores or apply the "
+ "'underscoresInNameBehavior' customization for this service (Supported "
+ "'underscoresInNameBehavior' values: %s).", name, location, supportedBehaviors)
));
}
if (behavior != UnderscoresInNameBehavior.ALLOW) {
throw ModelInvalidException.fromEntry(ValidationEntry.create(
ValidationErrorId.INVALID_CODEGEN_CUSTOMIZATION,
ValidationErrorSeverity.DANGER,
String.format(
"Unsupported underscoresInShapeNameBehavior: %s. Supported values: %s",
behavior, supportedBehaviors)
));
}
}

Validate.isTrue(VALID_IDENTIFIER_NAME.matcher(name).matches(),
"Encountered a name or identifier that is invalid within Java (%s in %s). Please remove invalid "
+ "characters.", name, location);
if (!VALID_IDENTIFIER_NAME.matcher(name).matches()) {
throw ModelInvalidException.fromEntry(ValidationEntry.create(
ValidationErrorId.INVALID_IDENTIFIER_NAME,
ValidationErrorSeverity.DANGER,
String.format(
"Encountered a name or identifier that is invalid within Java (%s in %s). Please remove invalid "
+ "characters.", name, location)
));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@
import software.amazon.awssdk.codegen.poet.ClassSpec;
import software.amazon.awssdk.codegen.poet.PoetExtension;
import software.amazon.awssdk.codegen.poet.model.TypeProvider;
import software.amazon.awssdk.codegen.validation.ModelInvalidException;
import software.amazon.awssdk.codegen.validation.ValidationEntry;
import software.amazon.awssdk.codegen.validation.ValidationErrorId;
import software.amazon.awssdk.codegen.validation.ValidationErrorSeverity;
import software.amazon.awssdk.core.util.PaginatorUtils;

public abstract class PaginatorsClassSpec implements ClassSpec {
Expand Down Expand Up @@ -64,7 +68,12 @@ public PaginatorsClassSpec(IntermediateModel model, String c2jOperationName, Pag
this.typeProvider = new TypeProvider(model);
this.operationModel = model.getOperation(c2jOperationName);
if (operationModel == null) {
throw new IllegalArgumentException("The service model does not model an operation '" + c2jOperationName + "'");
throw ModelInvalidException.fromEntry(ValidationEntry.create(
ValidationErrorId.UNKNOWN_OPERATION,
ValidationErrorSeverity.DANGER,
"Invalid paginator definition - The service model does not model the referenced operation '" +
c2jOperationName + "'"
));
}
this.paginationDocs = new PaginationDocs(model, operationModel, paginatorDefinition);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,9 @@ public enum ValidationErrorId {
REQUEST_URI_NOT_FOUND("The request URI does not exist."),

INVALID_CODEGEN_CUSTOMIZATION("A customization is enabled for this service that cannot be applied for the given service "
+ "model.")
;
+ "model."),
UNKNOWN_OPERATION("The model references an unknown operation."),
INVALID_IDENTIFIER_NAME("The model contains an invalid or non-idiomatic name or identifier.");

private final String description;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@
import software.amazon.awssdk.codegen.model.intermediate.IntermediateModel;
import software.amazon.awssdk.codegen.model.service.PaginatorDefinition;
import software.amazon.awssdk.codegen.poet.ClientTestModels;
import software.amazon.awssdk.codegen.validation.ModelInvalidException;

public class PaginatorsClassSpecTest {
@Test
public void constructor_unknownOperationName_throws() {
assertThatThrownBy(() -> new TestPaginatorSpec(ClientTestModels.awsJsonServiceModels(),
"~~DoesNotExist",
new PaginatorDefinition()))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("The service model does not model an operation '~~DoesNotExist'");
.isInstanceOf(ModelInvalidException.class)
.hasMessageContaining("Invalid paginator definition - "
+ "The service model does not model the referenced operation '~~DoesNotExist'");
}

private static class TestPaginatorSpec extends PaginatorsClassSpec {
Expand Down
Loading