adk_payments/auth/
error.rs1use adk_auth::AuthError;
2use adk_core::{AdkError, ErrorCategory, ErrorComponent};
3use thiserror::Error;
4
5use super::scopes::PaymentOperation;
6
7#[derive(Debug, Error)]
9pub enum PaymentsAuthError {
10 #[error(
11 "payment operation `{operation}` is missing required scopes {missing:?} (requires {required:?}). Grant the missing scopes before retrying the payment mutation."
12 )]
13 MissingScopes { operation: PaymentOperation, required: Vec<String>, missing: Vec<String> },
14
15 #[error(
16 "authenticated request value `{actual}` conflicts with transaction `{transaction_id}` binding `{binding}` expected `{expected}`. Reuse the original transaction identity instead of rebinding it implicitly."
17 )]
18 IdentityConflict {
19 transaction_id: String,
20 binding: &'static str,
21 expected: String,
22 actual: String,
23 },
24
25 #[error(
26 "failed to emit a payment audit event: {0}. Restore the configured audit sink before retrying the sensitive payment action."
27 )]
28 AuditSink(#[from] AuthError),
29}
30
31impl From<PaymentsAuthError> for AdkError {
32 fn from(value: PaymentsAuthError) -> Self {
33 match value {
34 PaymentsAuthError::MissingScopes { .. } => AdkError::new(
35 ErrorComponent::Auth,
36 ErrorCategory::Forbidden,
37 "payments.auth.scope_denied",
38 value.to_string(),
39 ),
40 PaymentsAuthError::IdentityConflict { .. } => AdkError::new(
41 ErrorComponent::Auth,
42 ErrorCategory::Forbidden,
43 "payments.auth.identity_conflict",
44 value.to_string(),
45 ),
46 PaymentsAuthError::AuditSink(err) => AdkError::new(
47 ErrorComponent::Auth,
48 ErrorCategory::Internal,
49 "payments.auth.audit_failed",
50 err.to_string(),
51 )
52 .with_source(err),
53 }
54 }
55}