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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions