Skip to content

Improve exception handling for missing converters - #7327

Open
andreas-grafenberger wants to merge 1 commit into
aws:masterfrom
andreas-grafenberger:feature/improve_missing_converters_exception_handling
Open

Improve exception handling for missing converters#7327
andreas-grafenberger wants to merge 1 commit into
aws:masterfrom
andreas-grafenberger:feature/improve_missing_converters_exception_handling

Conversation

@andreas-grafenberger

@andreas-grafenberger andreas-grafenberger commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Motivation and Context

The DynamoDB Enhanced Client requires generic type information to create collection converters. Raw Map, Set, and List declarations do not provide that information. Earlier converter resolution could access a missing type parameter and throw an IndexOutOfBoundsException.

Plain Object requires separate handling. Because Object is a supertype of the collection interfaces, it could enter collection routing even though it is not a collection and the default provider has no Object converter.

Nested collection failures also did not always identify the actual missing type. For example, Map<String, Object> requires a converter for Object, so the error should identify Object rather than the enclosing map.

Changes

This change improves validation and diagnostics while preserving existing collection-routing behavior.

  • DefaultAttributeConverterProvider excludes plain Object from collection routing.
  • Raw Map, Set, and List declarations are validated before their type parameters are accessed.
  • Nested list members, set members, and map values are resolved through the public converter lookup. A missing converter now identifies the missing nested type.
  • DefaultEnhancedDocument applies the same Object guard and raw-type validation to its direct list and map conversion paths.
  • The configured converter-provider chain remains available for Object and other custom types. Applications can provide an AttributeConverter<Object> when they define the required serialization behavior.

Behavior and Compatibility

The existing collection-routing precedence remains map, then set, then list. This preserves the existing behavior of Collection<T> and Iterable<T>, which resolve through the set converter.

Declaration Result
Map<String, Integer>, Set<String>, and List<String> Supported when the required converters are available.
Collection<String> and Iterable<String> Supported with existing set-converter behavior.
SequencedCollection<String> Supported through the existing hierarchy on Java 21 and later.
Raw Map, Set, and List Rejected with an IllegalStateException stating that type parameters are required.
Plain Object with only default converters Rejected because no default Object converter exists.
Map<String, Object>, Set<Object>, and List<Object> with only default converters Rejected with Converter not found for EnhancedType(java.lang.Object).
Nested unsupported member or map value Rejected with an error for the missing nested type.
Plain or nested Object with a custom converter Supported when the configured provider chain returns an AttributeConverter<Object>.
HashMap, HashSet, ArrayList, and other concrete collection declarations Remain unsupported by the default provider.

No public APIs, annotations, schemas, dependencies, or DynamoDB wire representations are changed.

Testing

The updated tests cover converter lookup, caching, conversion, and registration. They cover parameterized and raw Map, Set, List, Collection, and Iterable declarations, concrete collection implementations, plain Object, custom Object converters, and nested missing member types.

Bean, immutable, document, static, static immutable, nested, and flattened schema paths are covered. Existing sync and async CRUD, scan, query, batch, transaction, null handling, and extension tests continue to exercise the Enhanced Client.

Test Coverage on modified classes

image

Test coverage checklist

Scenario Covered Comments
1. Different TableSchema Creation Methods [x]
a. TableSchema.fromBean(Customer.class) [x]
b. TableSchema.fromImmutableClass(Customer.class) [x]
c. TableSchema.documentSchemaBuilder().build() [x]
d. StaticTableSchema.builder(Customer.class) [x]
2. Nesting of Different TableSchema Types [x]
a. Bean with nested bean as non-null [x]
b. Bean with nested immutable as non-null [x]
c. Immutable with nested bean as non-null [x]
d. Bean with nested bean as null [x]
e. Bean with nested immutable as null [x]
f. Immutable with nested bean as null [x]
3. CRUD Operations [x] Sync, async, functional, and integration coverage exists.
a. scan() [x]
b. query() [x]
c. updateItem() [x]
d. putItem() [x]
e. getItem() [x]
f. deleteItem() [x]
g. batchGetItem() [x]
h. batchWriteItem() [x]
i. transactGetItems() [x]
j. transactWriteItems() [x]
4. Data Types and Null Handling [x]
a. Top-level null attributes [x]
b. Collections with null elements [x]
c. Maps with null values [x]
d. Conversion between null Java values and AttributeValue [x]
e. Serialization and deserialization cycle with null values [x]
5. AsyncTable and SyncTable [x]
a. DynamoDbAsyncTable [x]
b. DynamoDbTable [x]
6. New or Modification in Extensions [x] Existing extension coverage remains applicable. This change does not modify extensions.
a. All TableSchema methods with extensions [ ] No extension implementation changes.
b. Default values in annotations [ ] Not changed by this PR.
c. Annotation and builder combination through extensions [ ] No new coverage added for this combination.
7. New or Modification in Converters [x] Core focus of this PR.
a. All TableSchema creation methods [x]
b. Default values in annotations [ ] Converter routing does not modify annotation default-value behavior.
c. Scenarios from sections 1 to 5 [x]
8. Shared Client Cross Table Behavior [ ] No shared client configuration changes.
a. Supported and unsupported or custom schema tables on one client [ ] No mixed schema client scenario added.
b. Extension-enabled shared client [ ] No shared client extension scenario added.
c. Cache isolation [x] DefaultAttributeConverterProviderCacheTest covers converter caching.
d. Async shared-client scenarios [ ] No async shared client scenario added.
9. Extension Interaction Matrix [ ] No extension implementation changes.
a. Default and custom extension-chain ordering [x] Existing ChainExtensionTest coverage.
b. Auto timestamp and versioning on the same item [ ] This change does not modify extension interaction behavior.
c. Auto UUID and update behavior interaction [ ] This change does not modify auto UUID or update behavior.
d. Extensions with condition expressions [ ] This change does not affect condition expression processing.
e. Extensions in batch and transaction flows [ ] This change does not modify extension execution in batch or transaction requests.
10. Nested and Flattened Cross Operation Invariants [x] Existing nested and flattened coverage remains applicable.
a. Flattened attributes across chained operations [ ] No cross operation validation changes.
b. Flattened maps with mixed scalar, map, and list payloads [ ] No flattened payload conversion changes.
c. Nested projection and filter combinations [ ] This change does not alter projection or filter expression behavior.
d. Nested structures with partition, sort, or index tags [x] Existing FlattenWithTagsTest coverage.
e. Sync and async parity for nested and flattened invariants [ ] No sync or async table behavior changes.
11. Mixed Schema Multi Table Request [ ] No multi table request changes.
a. Mixed-schema batchGet [ ] No batchGet request changes.
b. Mixed-schema batchWrite [ ] No batchWrite request changes.
c. Mixed-schema transactGet [ ] No transactGet request changes.
d. Mixed-schema transactWrite [ ] No transactWrite request changes.
e. Partial success and failure diagnostics [ ] No request diagnostic or partial-result handling changes.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)

Checklist

  • I have read the CONTRIBUTING document.
  • Local run of mvn install succeeds.
  • My code follows the code style of this project.
  • My change requires a change to the Javadoc documentation.
  • I have updated the Javadoc documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • I have added a changelog entry.
  • My change is to implement a 1.11 parity feature and I have updated LaunchChangelog.

License

  • I confirm that this pull request can be released under the Apache 2 license.

@andreas-grafenberger
andreas-grafenberger requested a review from a team as a code owner August 27, 2026 07:47
@andreas-grafenberger
andreas-grafenberger marked this pull request as draft August 27, 2026 08:08
@andreas-grafenberger
andreas-grafenberger force-pushed the feature/improve_missing_converters_exception_handling branch from 27fedb8 to c3b8815 Compare September 3, 2026 06:20
@anasatirbasa
anasatirbasa force-pushed the feature/improve_missing_converters_exception_handling branch 2 times, most recently from d313166 to 6a44db3 Compare September 4, 2026 15:05
@andreas-grafenberger
andreas-grafenberger marked this pull request as ready for review September 4, 2026 15:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants