Skip to content

fix: HTTP exception classification — separate permanent from retriable failures#44

Merged
endrju19 merged 1 commit into
mainfrom
fix/http-exception-classification
May 14, 2026
Merged

fix: HTTP exception classification — separate permanent from retriable failures#44
endrju19 merged 1 commit into
mainfrom
fix/http-exception-classification

Conversation

@endrju19
Copy link
Copy Markdown
Collaborator

Summary

HttpMessageDeliverer.deliver() previously caught all exceptions as RetriableFailure. This meant corrupt delivery metadata or an unknown service triggered an infinite retry loop instead of moving the entry to FAILED.

This PR classifies exceptions explicitly:

Exception Classification Why
JsonProcessingException PermanentFailure Corrupt metadata won't fix itself (caught before IOException — it's a subtype)
IOException RetriableFailure Connection / timeout — transient
InterruptedException RetriableFailure Interrupt flag restored; consistent with KafkaMessageDeliverer
other Exception PermanentFailure Malformed URI, unknown service, IllegalStateException from ServiceUrlResolver, etc.

Why this matters

Before: okapi-http consumer with malformed JSON in deliveryMetadata → infinite retries → retry storm in logs, entry never marked FAILED, operator alert fatigue.

After: corrupt input → PermanentFailure → entry moves to FAILED per RetryPolicy, ops visibility preserved.

Scope

  • HttpMessageDeliverer.kt: refactor to expression-body, granular catch blocks, updated KDoc
  • HttpMessageDelivererTest.kt: 2 new tests
    • corrupt metadata → PermanentFailure (does not throw)
    • urlResolver throwing → PermanentFailure (does not throw)

Independent of the Kafka deliverBatch work in PR #40.

Test plan

  • ./gradlew :okapi-http:test ktlintCheck — all 13 unit tests pass (11 existing + 2 new)

…e failures

Previously, a single generic catch (e: Exception) mapped all errors to
RetriableFailure. Corrupt delivery metadata or an unknown service therefore
triggered an infinite retry loop instead of moving the entry to FAILED.

Now classified explicitly:
- JsonProcessingException (corrupt metadata) → PermanentFailure
  (caught before IOException — it's a subtype)
- IOException (connection/timeout) → RetriableFailure
- InterruptedException → RetriableFailure (interrupt flag restored,
  consistent with KafkaMessageDeliverer)
- other Exception (malformed URI, unknown service, IllegalStateException
  from ServiceUrlResolver) → PermanentFailure

Adds two unit tests covering the new classification paths:
- corrupt delivery metadata → PermanentFailure
- urlResolver throwing → PermanentFailure
@endrju19 endrju19 merged commit acbca8e into main May 14, 2026
8 checks passed
@endrju19 endrju19 deleted the fix/http-exception-classification branch May 14, 2026 12:08
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.

1 participant