mirror of
				https://github.com/juspay/hyperswitch.git
				synced 2025-11-04 14:07:18 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			107 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
//! Errors and error specific types for universal use
 | 
						|
 | 
						|
/// Custom Result
 | 
						|
/// A custom datatype that wraps the error variant <E> into a report, allowing
 | 
						|
/// error_stack::Report<E> specific extendability
 | 
						|
///
 | 
						|
/// Effectively, equivalent to `Result<T, error_stack::Report<E>>`
 | 
						|
///
 | 
						|
pub type CustomResult<T, E> = error_stack::Result<T, E>;
 | 
						|
 | 
						|
macro_rules! impl_error_display {
 | 
						|
    ($st: ident, $arg: tt) => {
 | 
						|
        impl std::fmt::Display for $st {
 | 
						|
            fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
 | 
						|
                fmt.write_str(&format!(
 | 
						|
                    "{{ error_type: {:?}, error_description: {} }}",
 | 
						|
                    self, $arg
 | 
						|
                ))
 | 
						|
            }
 | 
						|
        }
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
macro_rules! impl_error_type {
 | 
						|
    ($name: ident, $arg: tt) => {
 | 
						|
        #[doc = ""]
 | 
						|
        #[doc = stringify!(Error variant $name)]
 | 
						|
        #[doc = stringify!(Custom error variant for $arg)]
 | 
						|
        #[doc = ""]
 | 
						|
        #[derive(Debug)]
 | 
						|
        pub struct $name;
 | 
						|
 | 
						|
        impl_error_display!($name, $arg);
 | 
						|
 | 
						|
        impl std::error::Error for $name {}
 | 
						|
    };
 | 
						|
}
 | 
						|
 | 
						|
impl_error_type!(ParsingError, "Parsing error");
 | 
						|
 | 
						|
/// Validation errors.
 | 
						|
#[allow(missing_docs)] // Only to prevent warnings about struct fields not being documented
 | 
						|
#[derive(Debug, thiserror::Error)]
 | 
						|
pub enum ValidationError {
 | 
						|
    /// The provided input is missing a required field.
 | 
						|
    #[error("Missing required field: {field_name}")]
 | 
						|
    MissingRequiredField { field_name: String },
 | 
						|
 | 
						|
    /// An incorrect value was provided for the field specified by `field_name`.
 | 
						|
    #[error("Incorrect value provided for field: {field_name}")]
 | 
						|
    IncorrectValueProvided { field_name: &'static str },
 | 
						|
 | 
						|
    /// An invalid input was provided.
 | 
						|
    #[error("{message}")]
 | 
						|
    InvalidValue { message: String },
 | 
						|
}
 | 
						|
 | 
						|
/// Cryptographic algorithm errors
 | 
						|
#[derive(Debug, thiserror::Error)]
 | 
						|
pub enum CryptoError {
 | 
						|
    /// The cryptographic algorithm was unable to encode the message
 | 
						|
    #[error("Failed to encode given message")]
 | 
						|
    EncodingFailed,
 | 
						|
    /// The cryptographic algorithm was unable to decode the message
 | 
						|
    #[error("Failed to decode given message")]
 | 
						|
    DecodingFailed,
 | 
						|
    /// The cryptographic algorithm was unable to sign the message
 | 
						|
    #[error("Failed to sign message")]
 | 
						|
    MessageSigningFailed,
 | 
						|
    /// The cryptographic algorithm was unable to verify the given signature
 | 
						|
    #[error("Failed to verify signature")]
 | 
						|
    SignatureVerificationFailed,
 | 
						|
}
 | 
						|
 | 
						|
/// Allows [error_stack::Report] to change between error contexts
 | 
						|
/// using the dependent [ErrorSwitch] trait to define relations & mappings between traits
 | 
						|
pub trait ReportSwitchExt<T, U> {
 | 
						|
    /// Switch to the intended report by calling switch
 | 
						|
    /// requires error switch to be already implemented on the error type
 | 
						|
    fn switch(self) -> Result<T, error_stack::Report<U>>;
 | 
						|
}
 | 
						|
 | 
						|
impl<T, U, V> ReportSwitchExt<T, U> for Result<T, error_stack::Report<V>>
 | 
						|
where
 | 
						|
    V: ErrorSwitch<U> + error_stack::Context,
 | 
						|
    U: error_stack::Context,
 | 
						|
{
 | 
						|
    #[track_caller]
 | 
						|
    fn switch(self) -> Result<T, error_stack::Report<U>> {
 | 
						|
        match self {
 | 
						|
            Ok(i) => Ok(i),
 | 
						|
            Err(er) => {
 | 
						|
                let new_c = er.current_context().switch();
 | 
						|
                Err(er.change_context(new_c))
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/// Allow [error_stack::Report] to convert between error types
 | 
						|
/// This autoimplements [ReportSwitchExt] for the corresponding errors
 | 
						|
pub trait ErrorSwitch<T> {
 | 
						|
    /// Get the next error type that the source error can be escalated into
 | 
						|
    /// This does not consume the source error since we need to keep it in context
 | 
						|
    fn switch(&self) -> T;
 | 
						|
}
 |