jsonrpc_lite/
error.rs

1//! JSON-RPC 2.0 errors
2//!
3//! This module provides error handling types and utilities for JSON-RPC 2.0 protocol.
4//! It includes standard error codes as defined in the JSON-RPC 2.0 specification
5//! and a comprehensive Error type for representing JSON-RPC errors.
6
7use serde::{Deserialize, Serialize};
8use serde_json::Value;
9use std::error;
10use std::fmt;
11use std::result;
12
13/// Standard JSON-RPC 2.0 error codes
14///
15/// This enum represents the predefined error codes as specified in the JSON-RPC 2.0
16/// specification, along with support for custom server error codes.
17#[derive(Clone, Debug, PartialEq, Eq)]
18pub enum ErrorCode {
19    /// Invalid JSON was received by the server.
20    /// An error occurred on the server while parsing the JSON text.
21    /// Error code: -32700
22    ParseError,
23    /// The JSON sent is not a valid Request object.
24    /// Error code: -32600
25    InvalidRequest,
26    /// The method does not exist / is not available.
27    /// Error code: -32601
28    MethodNotFound,
29    /// Invalid method parameter(s).
30    /// Error code: -32602
31    InvalidParams,
32    /// Internal JSON-RPC error.
33    /// Error code: -32603
34    InternalError,
35    /// Reserved for implementation-defined server-errors.
36    /// Error codes from -32000 to -32099 are reserved for implementation-defined server-errors.
37    /// The `i64` value represents the custom error code.
38    ServerError(i64),
39}
40
41impl ErrorCode {
42    /// Returns the numeric error code as defined in the JSON-RPC 2.0 specification
43    ///
44    /// # Returns
45    ///
46    /// The corresponding error code number:
47    /// - ParseError: -32700
48    /// - InvalidRequest: -32600
49    /// - MethodNotFound: -32601
50    /// - InvalidParams: -32602
51    /// - InternalError: -32603
52    /// - ServerError: the custom code provided
53    pub fn code(&self) -> i64 {
54        match *self {
55            ErrorCode::ParseError => -32700,
56            ErrorCode::InvalidRequest => -32600,
57            ErrorCode::MethodNotFound => -32601,
58            ErrorCode::InvalidParams => -32602,
59            ErrorCode::InternalError => -32603,
60            ErrorCode::ServerError(code) => code,
61        }
62    }
63
64    /// Returns a human-readable description of the error
65    ///
66    /// # Returns
67    ///
68    /// A static string slice containing the error description
69    pub fn as_str(&self) -> &'static str {
70        match *self {
71            ErrorCode::ParseError => "Parse error",
72            ErrorCode::InvalidRequest => "Invalid request",
73            ErrorCode::MethodNotFound => "Method not found",
74            ErrorCode::InvalidParams => "Invalid params",
75            ErrorCode::InternalError => "Internal error",
76            ErrorCode::ServerError(_) => "Server error",
77        }
78    }
79}
80
81impl fmt::Display for ErrorCode {
82    /// Formats the error code as a string
83    ///
84    /// # Arguments
85    ///
86    /// * `f` - The formatter to write the error code to
87    ///
88    /// # Returns
89    ///
90    /// A `fmt::Result` indicating success or failure of the formatting operation
91    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92        write!(f, "{}", self.as_str())
93    }
94}
95
96/// JSON-RPC 2.0 Error Object
97///
98/// Represents an error that occurred during the processing of a JSON-RPC request.
99/// This struct follows the JSON-RPC 2.0 specification for error objects.
100///
101/// # Fields
102///
103/// * `code` - A number that indicates the error type that occurred
104/// * `message` - A string providing a short description of the error
105/// * `data` - Optional additional information about the error
106#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
107pub struct Error {
108    /// The error code number
109    pub code: i64,
110    /// A short description of the error
111    pub message: String,
112    /// Optional additional error data
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub data: Option<Value>,
115}
116
117impl Error {
118    /// Creates a new Error from an ErrorCode
119    ///
120    /// # Arguments
121    ///
122    /// * `code` - The error code to create the error from
123    ///
124    /// # Returns
125    ///
126    /// A new `Error` instance with the appropriate code and message
127    ///
128    /// # Examples
129    ///
130    /// ```
131    /// use jsonrpc_lite::error::{Error, ErrorCode};
132    ///
133    /// let error = Error::new(ErrorCode::MethodNotFound);
134    /// assert_eq!(error.code, -32601);
135    /// assert_eq!(error.message, "Method not found");
136    /// ```
137    pub fn new(code: ErrorCode) -> Self {
138        Error {
139            code: code.code(),
140            message: code.to_string(),
141            data: None,
142        }
143    }
144
145    /// Creates a parse error (-32700)
146    ///
147    /// # Returns
148    ///
149    /// A new `Error` instance representing a parse error
150    pub fn parse_error() -> Self {
151        Self::new(ErrorCode::ParseError)
152    }
153
154    /// Creates an invalid request error (-32600)
155    ///
156    /// # Returns
157    ///
158    /// A new `Error` instance representing an invalid request error
159    pub fn invalid_request() -> Self {
160        Self::new(ErrorCode::InvalidRequest)
161    }
162
163    /// Creates a method not found error (-32601)
164    ///
165    /// # Returns
166    ///
167    /// A new `Error` instance representing a method not found error
168    pub fn method_not_found() -> Self {
169        Self::new(ErrorCode::MethodNotFound)
170    }
171
172    /// Creates an invalid params error (-32602)
173    ///
174    /// # Returns
175    ///
176    /// A new `Error` instance representing an invalid params error
177    pub fn invalid_params() -> Self {
178        Self::new(ErrorCode::InvalidParams)
179    }
180
181    /// Creates an internal error (-32603)
182    ///
183    /// # Returns
184    ///
185    /// A new `Error` instance representing an internal error
186    pub fn internal_error() -> Self {
187        Self::new(ErrorCode::InternalError)
188    }
189}
190
191impl error::Error for Error {
192    /// Returns a description of the error
193    ///
194    /// # Returns
195    ///
196    /// A string slice containing the error message
197    fn description(&self) -> &str {
198        &self.message
199    }
200}
201
202impl fmt::Display for Error {
203    /// Formats the error as a JSON string for display
204    ///
205    /// # Arguments
206    ///
207    /// * `f` - The formatter to write to
208    ///
209    /// # Returns
210    ///
211    /// A `fmt::Result` indicating success or failure of the formatting operation
212    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
213        write!(
214            f,
215            "{}",
216            serde_json::to_string(&self).unwrap_or_else(|_| self.message.clone())
217        )
218    }
219}
220
221/// A type alias for `Result<T, Error>`
222///
223/// This is a convenience type that represents either a successful result of type `T`
224/// or a JSON-RPC error.
225pub type Result<T> = result::Result<T, Error>;