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>;