Skip to main content

cala_ledger/velocity/
error.rs

1use rust_decimal::Decimal;
2use thiserror::Error;
3
4use cel_interpreter::CelError;
5
6use crate::primitives::*;
7
8use super::control::{
9    VelocityControlColumn, VelocityControlCreateError, VelocityControlFindError,
10    VelocityControlModifyError, VelocityControlQueryError,
11};
12use super::limit::{
13    VelocityLimitColumn, VelocityLimitCreateError, VelocityLimitFindError,
14    VelocityLimitModifyError, VelocityLimitQueryError,
15};
16
17#[derive(Error, Debug)]
18pub enum VelocityError {
19    #[error("VelocityError - Sqlx: {0}")]
20    Sqlx(sqlx::Error),
21    #[error("VelocityError - CelError: {0}")]
22    CelError(#[from] CelError),
23    #[error("{0}")]
24    ParamError(#[from] crate::param::error::ParamError),
25    #[error("VelocityError - Could not find control by id: {0}")]
26    CouldNotFindControlById(VelocityControlId),
27    #[error("VelocityError - Enforcement: {0}")]
28    Enforcement(#[from] LimitExceededError),
29    #[error("VelocityError - HydrationError: {0}")]
30    HydrationError(#[from] es_entity::EntityHydrationError),
31    #[error("VelocityError - VelocityControlCreate: {0}")]
32    VelocityControlCreate(VelocityControlCreateError),
33    #[error("VelocityError - VelocityControlModify: {0}")]
34    VelocityControlModify(#[from] VelocityControlModifyError),
35    #[error("VelocityError - VelocityControlFind: {0}")]
36    VelocityControlFind(VelocityControlFindError),
37    #[error("VelocityError - VelocityControlQuery: {0}")]
38    VelocityControlQuery(#[from] VelocityControlQueryError),
39    #[error("VelocityError - VelocityLimitCreate: {0}")]
40    VelocityLimitCreate(VelocityLimitCreateError),
41    #[error("VelocityError - VelocityLimitModify: {0}")]
42    VelocityLimitModify(#[from] VelocityLimitModifyError),
43    #[error("VelocityError - VelocityLimitFind: {0}")]
44    VelocityLimitFind(#[from] VelocityLimitFindError),
45    #[error("VelocityError - VelocityLimitQuery: {0}")]
46    VelocityLimitQuery(#[from] VelocityLimitQueryError),
47    #[error("VelocityError - control_id '{0}' already exists")]
48    ControlIdAlreadyExists(String),
49    #[error("VelocityError - limit_id '{0}' already exists")]
50    LimitIdAlreadyExists(String),
51    #[error("VelocityError - Limit already added to Control")]
52    LimitAlreadyAddedToControl,
53}
54
55impl From<VelocityControlFindError> for VelocityError {
56    fn from(error: VelocityControlFindError) -> Self {
57        match error {
58            VelocityControlFindError::NotFound {
59                column: Some(VelocityControlColumn::Id),
60                value,
61                ..
62            } => Self::CouldNotFindControlById(value.parse().expect("invalid uuid")),
63            other => Self::VelocityControlFind(other),
64        }
65    }
66}
67
68impl From<sqlx::Error> for VelocityError {
69    fn from(error: sqlx::Error) -> Self {
70        if let Some(err) = error.as_database_error() {
71            if let Some(constraint) = err.constraint() {
72                if constraint
73                    .contains("cala_velocity_control_limits_velocity_control_id_velocity_l_key")
74                {
75                    return Self::LimitAlreadyAddedToControl;
76                }
77            }
78        }
79        Self::Sqlx(error)
80    }
81}
82
83impl From<VelocityControlCreateError> for VelocityError {
84    fn from(error: VelocityControlCreateError) -> Self {
85        match error {
86            VelocityControlCreateError::ConstraintViolation {
87                column: Some(VelocityControlColumn::Id),
88                value,
89                ..
90            } => Self::ControlIdAlreadyExists(value.unwrap_or_default()),
91            other => Self::VelocityControlCreate(other),
92        }
93    }
94}
95
96impl From<VelocityLimitCreateError> for VelocityError {
97    fn from(error: VelocityLimitCreateError) -> Self {
98        match error {
99            VelocityLimitCreateError::ConstraintViolation {
100                column: Some(VelocityLimitColumn::Id),
101                value,
102                ..
103            } => Self::LimitIdAlreadyExists(value.unwrap_or_default()),
104            other => Self::VelocityLimitCreate(other),
105        }
106    }
107}
108
109#[derive(Error, Debug)]
110#[error("Velocity limit exceeded")]
111pub struct LimitExceededError {
112    pub account_id: AccountId,
113    pub currency: Currency,
114    pub limit_id: VelocityLimitId,
115    pub layer: Layer,
116    pub direction: DebitOrCredit,
117    pub limit: Decimal,
118    pub requested: Decimal,
119}