open_payments/client/
error.rs

1//! # Open Payments Client Error Types
2//!
3//! This module defines the error types used throughout the Open Payments client.
4//! All client operations return a [`Result<T, OpClientError>`] which provides
5//! detailed error information for different failure scenarios.
6//!
7//! ## Error Categories
8//!
9//! - **HTTP Errors**: Network and HTTP protocol errors
10//! - **Parsing Errors**: Header, URL, and data parsing failures
11//! - **Cryptographic Errors**: Key and signature-related issues
12//! - **I/O Errors**: File system and network I/O problems
13//!
14//! ## Example Usage
15//!
16//! ```rust
17//! use open_payments::client::{OpClientError, Result};
18//!
19//! fn handle_client_error(result: Result<()>) {
20//!     match result {
21//!         Ok(()) => println!("Operation successful"),
22//!         Err(OpClientError::Http(msg)) => eprintln!("HTTP error: {}", msg),
23//!         Err(OpClientError::Signature(msg)) => eprintln!("Signature error: {}", msg),
24//!         Err(OpClientError::Other(msg)) => eprintln!("Other error: {}", msg),
25//!         Err(e) => eprintln!("Unexpected error: {:?}", e),
26//!     }
27//! }
28//! ```
29
30use thiserror::Error;
31
32/// Error type for Open Payments client operations.
33///
34/// This enum provides detailed error information for different types of failures
35/// that can occur during client operations. Each variant includes context-specific
36/// error messages to help with debugging and error handling.
37///
38/// ## Error Variants
39///
40/// - `Http` - Network and HTTP protocol errors
41/// - `HeaderParse` - HTTP header parsing failures
42/// - `Serde` - JSON serialization/deserialization errors
43/// - `Io` - File system and I/O errors
44/// - `Pem` - PEM format parsing errors
45/// - `Pkcs8` - PKCS8 key format errors
46/// - `Base64` - Base64 encoding/decoding errors
47/// - `Url` - URL parsing errors
48/// - `Signature` - Cryptographic signature errors
49/// - `Other` - Miscellaneous errors
50#[derive(Debug, Error)]
51pub enum OpClientError {
52    /// HTTP protocol or network-related errors.
53    ///
54    /// This includes connection failures, timeout errors, and HTTP status code errors.
55    /// The error message provides details about the specific HTTP issue.
56    #[error("HTTP error: {0}")]
57    Http(String),
58
59    /// HTTP header parsing errors.
60    ///
61    /// Occurs when the client cannot parse required HTTP headers such as
62    /// `Content-Type`, `Authorization`, or custom headers.
63    #[error("Header parse error: {0}")]
64    HeaderParse(String),
65
66    /// JSON serialization or deserialization errors.
67    ///
68    /// This error is automatically converted from `serde_json::Error` and occurs
69    /// when the client cannot serialize request data or deserialize response data.
70    #[error("Serde error: {0}")]
71    Serde(#[from] serde_json::Error),
72
73    /// File system and I/O errors.
74    ///
75    /// This error is automatically converted from `std::io::Error` and occurs
76    /// when the client cannot read key files or perform other I/O operations.
77    #[error("IO error: {0}")]
78    Io(#[from] std::io::Error),
79
80    /// PEM format parsing errors.
81    ///
82    /// Occurs when the client cannot parse PEM-encoded private keys or certificates.
83    /// This includes malformed PEM files or unsupported PEM types.
84    #[error("Invalid PEM: {0}")]
85    Pem(String),
86
87    /// PKCS8 key format errors.
88    ///
89    /// Occurs when the client cannot parse PKCS8-encoded private keys.
90    /// This includes unsupported key algorithms or malformed key data.
91    #[error("PKCS8 error: {0}")]
92    Pkcs8(String),
93
94    /// Base64 encoding or decoding errors.
95    ///
96    /// This error is automatically converted from `base64::DecodeError` and occurs
97    /// when the client cannot decode Base64-encoded data such as signatures or keys.
98    #[error("Base64 error: {0}")]
99    Base64(#[from] base64::DecodeError),
100
101    /// URL parsing errors.
102    ///
103    /// This error is automatically converted from `url::ParseError` and occurs
104    /// when the client cannot parse URLs for wallet addresses or API endpoints.
105    #[error("URL parse error: {0}")]
106    Url(#[from] url::ParseError),
107
108    /// Cryptographic signature errors.
109    ///
110    /// Occurs when there are issues with HTTP message signature creation or validation.
111    /// This includes key loading failures, signature generation errors, and validation failures.
112    #[error("Signature error: {0}")]
113    Signature(String),
114
115    /// Miscellaneous errors that don't fit into other categories.
116    ///
117    /// This variant is used for unexpected errors that don't fall into the standard error categories.
118    #[error("Other error: {0}")]
119    Other(String),
120}
121
122impl From<reqwest::Error> for OpClientError {
123    /// Converts reqwest HTTP errors to `OpClientError::Http`.
124    ///
125    /// This implementation allows the client to automatically convert reqwest errors
126    /// into the unified error type, providing consistent error handling across the library.
127    fn from(err: reqwest::Error) -> Self {
128        OpClientError::Http(format!("{}", err))
129    }
130}
131
132/// Result type for Open Payments client operations.
133///
134/// This is a type alias for `Result<T, OpClientError>` that provides a convenient
135/// way to handle client operation results with detailed error information.
136pub type Result<T> = std::result::Result<T, OpClientError>;