Skip to main content

adk_payments/kernel/
errors.rs

1use adk_core::{AdkError, ErrorCategory, ErrorComponent};
2use thiserror::Error;
3
4use crate::domain::{OrderState, ReceiptState};
5
6/// Local kernel errors that map into the ADK structured error envelope.
7#[derive(Debug, Error, PartialEq, Eq)]
8pub enum PaymentsKernelError {
9    #[error(
10        "invalid transaction state transition from {from:?} to {to:?}. Move through the canonical checkout phases instead of skipping payment state."
11    )]
12    InvalidTransactionTransition { from: &'static str, to: &'static str },
13
14    #[error(
15        "invalid order state transition from {from:?} to {to:?}. Apply authorization and fulfillment updates in canonical order."
16    )]
17    InvalidOrderTransition { from: OrderState, to: OrderState },
18
19    #[error(
20        "invalid receipt state transition from {from:?} to {to:?}. Apply authorization, settlement, and refund updates in canonical order."
21    )]
22    InvalidReceiptTransition { from: ReceiptState, to: ReceiptState },
23
24    #[error(
25        "unsupported canonical action `{action}` for protocol `{protocol}`. Return an explicit unsupported response instead of approximating semantics."
26    )]
27    UnsupportedAction { action: String, protocol: String },
28
29    #[error(
30        "payment policy denied `{action}` for transaction `{transaction_id}`. Require explicit user approval or adjust policy before retrying."
31    )]
32    PolicyDenied { action: String, transaction_id: String },
33}
34
35impl From<PaymentsKernelError> for AdkError {
36    fn from(value: PaymentsKernelError) -> Self {
37        let message = value.to_string();
38
39        match value {
40            PaymentsKernelError::InvalidTransactionTransition { .. } => AdkError::new(
41                ErrorComponent::Server,
42                ErrorCategory::InvalidInput,
43                "payments.transaction.invalid_transition",
44                message,
45            ),
46            PaymentsKernelError::InvalidOrderTransition { .. } => AdkError::new(
47                ErrorComponent::Server,
48                ErrorCategory::InvalidInput,
49                "payments.order.invalid_transition",
50                message,
51            ),
52            PaymentsKernelError::InvalidReceiptTransition { .. } => AdkError::new(
53                ErrorComponent::Server,
54                ErrorCategory::InvalidInput,
55                "payments.receipt.invalid_transition",
56                message,
57            ),
58            PaymentsKernelError::UnsupportedAction { .. } => AdkError::new(
59                ErrorComponent::Server,
60                ErrorCategory::Unsupported,
61                "payments.action.unsupported",
62                message,
63            ),
64            PaymentsKernelError::PolicyDenied { .. } => AdkError::new(
65                ErrorComponent::Guardrail,
66                ErrorCategory::Forbidden,
67                "payments.policy.denied",
68                message,
69            ),
70        }
71    }
72}