Priority: P2 - Important
Tier: 3 - Advanced Features
Effort: Medium/Large (8-12 hours)
Goal
When generated mapper methods fail (ToItem / FromItem), throw errors that contain enough context to immediately understand what mapping failed and where.
Today failures tend to surface as generic exceptions (e.g., InvalidOperationException, FormatException, ArgumentException, NotImplementedException) without mapper/member/field context.
Desired behavior
When an error occurs during mapping, throw a DynamoMappingException that includes:
- Mapper type name
- Target CLR type name
- Which mapper method was running (
ToItem vs FromItem, and ideally the method name)
- The member name being mapped (when known)
- The DynamoDB field name (attribute key) (when known)
- Underlying exception details (preserve inner exception)
The exception should be actionable for production debugging.
Already in codebase
- A
DynamoMappingException exists: src/LayeredCraft.DynamoMapper.Runtime/DynamoMappingException.cs.
- It currently includes:
Mapper, TargetType, FieldName, MemberName, Details.
Scope
1) Runtime exceptions should be contextual
2) Generated mapper methods should wrap failures
In generated code, wrap mapping operations with try/catch and rethrow DynamoMappingException enriched with context.
Guidance:
- Prefer lightweight try/catch blocks that don’t allocate on success.
- Preserve
Exception innerException.
- When failure occurs while mapping a specific member, include that member + field info.
3) Provide a consistent pattern
Add a shared helper (runtime or generator-emitted local function) to avoid repeating formatting logic:
- e.g.,
DynamoMappingExceptionFactory (runtime) or emitted CreateMappingException(...) (generated).
Implementation notes
- Generator:
- Update
src/LayeredCraft.DynamoMapper.Generators/Templates/Mapper.scriban so each assignment can be wrapped or so the whole method is wrapped with additional context.
- If per-member granularity is desired, generate per-member try/catch blocks around the Get/Set call.
- Runtime:
- Consider adding a
MethodName property to DynamoMappingException (public API change) OR store method info in Details.
- Update
AttributeValueExtensions/* throw sites where practical.
Diagnostics / non-goals
Tests (must be part of this story)
Add tests verifying:
- Missing required key throws
DynamoMappingException (with mapper + field/member info).
- Invalid parse (e.g., bad Guid/DateTime) thrown from runtime is wrapped into
DynamoMappingException with inner exception preserved.
- The exception message/fields include enough context to identify the failing mapping.
Acceptance criteria
- Mapping failures consistently throw
DynamoMappingException with rich context.
- Inner exception is preserved.
- Tests cover at least required-missing and parse-failure scenarios.
Related issues
Priority: P2 - Important
Tier: 3 - Advanced Features
Effort: Medium/Large (8-12 hours)
Goal
When generated mapper methods fail (
ToItem/FromItem), throw errors that contain enough context to immediately understand what mapping failed and where.Today failures tend to surface as generic exceptions (e.g.,
InvalidOperationException,FormatException,ArgumentException,NotImplementedException) without mapper/member/field context.Desired behavior
When an error occurs during mapping, throw a
DynamoMappingExceptionthat includes:ToItemvsFromItem, and ideally the method name)The exception should be actionable for production debugging.
Already in codebase
DynamoMappingExceptionexists:src/LayeredCraft.DynamoMapper.Runtime/DynamoMappingException.cs.Mapper,TargetType,FieldName,MemberName,Details.Scope
1) Runtime exceptions should be contextual
DynamoMappingException.DynamoMappingException.2) Generated mapper methods should wrap failures
In generated code, wrap mapping operations with try/catch and rethrow
DynamoMappingExceptionenriched with context.Guidance:
Exception innerException.3) Provide a consistent pattern
Add a shared helper (runtime or generator-emitted local function) to avoid repeating formatting logic:
DynamoMappingExceptionFactory(runtime) or emittedCreateMappingException(...)(generated).Implementation notes
src/LayeredCraft.DynamoMapper.Generators/Templates/Mapper.scribanso each assignment can be wrapped or so the whole method is wrapped with additional context.MethodNameproperty toDynamoMappingException(public API change) OR store method info inDetails.AttributeValueExtensions/*throw sites where practical.Diagnostics / non-goals
Tests (must be part of this story)
Add tests verifying:
DynamoMappingException(with mapper + field/member info).DynamoMappingExceptionwith inner exception preserved.Acceptance criteria
DynamoMappingExceptionwith rich context.Related issues