Skip to content

Improve Mapper Method Error Handling (Include Mapping Context) #53

@j-d-ha

Description

@j-d-ha

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions