Skip to content

Preserve SerializableError in CachedError for proper error handling#77

Merged
cjustice merged 2 commits intomainfrom
preserve-serializable-error-in-cached-error
Jan 9, 2026
Merged

Preserve SerializableError in CachedError for proper error handling#77
cjustice merged 2 commits intomainfrom
preserve-serializable-error-in-cached-error

Conversation

@cjustice
Copy link
Copy Markdown
Contributor

@cjustice cjustice commented Jan 9, 2026

Preserve SerializableError in CachedError for proper error handling

Problem

When idempotent requests return cached errors, consumers receive CachedError instances but have no way to determine what the original exception type was. The SerializableError contains crucial type information (type: String with the fully qualified class name), but it was discarded when converting to CachedError.

This prevents consumers from properly mapping cached errors to appropriate error responses based on the exception type.

Current Behavior

// Before
SerializableError(
  type = "com.example.InsufficientBalanceException",
  message = "Insufficient balance"
)
  ↓
CachedError("[InsufficientBalanceException] Insufficient balance")
  // SerializableError is lost! ❌

Consumers receive the CachedError but cannot determine the original exception type programmatically.

Solution

Preserve the SerializableError as a field in CachedError so consumers can access the original exception type information and handle errors appropriately.

// After
SerializableError(
  type = "com.example.InsufficientBalanceException",
  message = "Insufficient balance"
)
  ↓
CachedError(
  message = "[InsufficientBalanceException] Insufficient balance",
  serializableError = SerializableError(...)  // ✅ Preserved!
)

Consumers can now access cachedError.serializableError.type to determine the original exception type.

Changes

common/src/main/kotlin/xyz/block/bittycity/common/idempotency/SerializableError.kt:

  1. Added serializableError: SerializableError field to CachedError data class
  2. Updated SerializableError.asCachedError() to pass this when constructing CachedError
data class CachedError(
  override val message: String?,
  val serializableError: SerializableError  // ← New field
) : Throwable(message)

fun SerializableError.asCachedError(): CachedError =
  CachedError("[$type] $message", this)  // ← Pass SerializableError

Impact

Breaking Change: Yes - CachedError constructor signature has changed.

Migration Path:

  • Recommended: Use SerializableError.asCachedError() (already updated)
  • If constructing directly: Add serializableError parameter to constructor calls

Benefits:

  • Consumers can properly handle cached errors based on exception type
  • No information loss during error serialization/caching
  • Enables type-based error handling in idempotent request flows

Example Consumer Usage

when (error) {
  is CachedError -> {
    // Can now inspect the original exception type
    when (error.serializableError.type) {
      "com.example.InsufficientBalanceException" -> handleInsufficientBalance()
      "com.example.InvalidParameterException" -> handleInvalidParameter()
      else -> handleGenericError()
    }
  }
  // ... handle other error types
}

cjustice and others added 2 commits January 9, 2026 14:06
Add serializableError field to CachedError to preserve exception type
information from cached idempotent requests. This enables consumers to
properly handle cached errors based on the original exception type.

Breaking change: CachedError constructor signature now requires
serializableError parameter.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Update test assertions to construct CachedError with SerializableError
parameter after adding serializableError field to CachedError data class.
@cjustice cjustice marked this pull request as ready for review January 9, 2026 19:21
@cjustice cjustice requested a review from a team as a code owner January 9, 2026 19:21
@cjustice cjustice merged commit 772cd2a into main Jan 9, 2026
3 checks passed
@cjustice cjustice deleted the preserve-serializable-error-in-cached-error branch January 9, 2026 21:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants