Shared adapter execution for sync and Oban worker dispatch paths.
Phase 14 contract changes (D-05)
classify/1 now returns a 3-tuple {outcome, error_class, detail} so
:temporary | :permanent | :bounced classification is preserved end-to-end:
adapter.deliver -> classify -> Deliveries.record_attempt(error_class:)
-> attempt row .error_class column
-> trace explanation
-> Oban worker {:ok | {:error, _}} returnrun_delivery/1 passes error_class into Deliveries.record_attempt/2. The
return shape is unchanged for sync consumers ({:ok, %{delivery, attempt}} |
{:error, step, reason, changes} | {:error, term()}). Plan 14-05's Oban
worker reads the recorded attempt's outcome + error_class to decide its
Oban return value (retry vs terminal vs success).
Summary
Functions
@spec run_delivery(Chimeway.Delivery.t()) :: {:ok, %{delivery: Chimeway.Delivery.t(), attempt: Chimeway.DeliveryAttempt.t()}} | {:error, atom(), term(), map()} | {:error, term()}