axum_jrpc/
error.rs

1use super::Value;
2
3use serde::{Deserialize, Serialize};
4use thiserror::Error;
5
6/// Constants for [error object](https://www.jsonrpc.org/specification#error_object)
7pub const INVALID_REQUEST: i32 = -32600;
8pub const METHOD_NOT_FOUND: i32 = -32601;
9pub const INVALID_PARAMS: i32 = -32602;
10pub const INTERNAL_ERROR: i32 = -32603;
11pub const PARSE_ERROR: i32 = -32700;
12
13#[derive(Debug, Clone, Copy)]
14pub enum JsonRpcErrorReason {
15    ParseError,
16    InvalidRequest,
17    MethodNotFound,
18    InvalidParams,
19    InternalError,
20    /// -32000 to -32099
21    ServerError(i32),
22    /// All other space
23    ApplicationError(i32),
24}
25
26impl std::fmt::Display for JsonRpcErrorReason {
27    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28        match self {
29            JsonRpcErrorReason::ParseError => write!(f, "Parse error"),
30            JsonRpcErrorReason::InvalidRequest => write!(f, "Invalid Request"),
31            JsonRpcErrorReason::MethodNotFound => write!(f, "Method not found"),
32            JsonRpcErrorReason::InvalidParams => write!(f, "Invalid params"),
33            JsonRpcErrorReason::InternalError => write!(f, "Internal error"),
34            JsonRpcErrorReason::ServerError(code) => write!(f, "Server error: {}", code),
35            JsonRpcErrorReason::ApplicationError(code) => {
36                write!(f, "Application error: {}", code)
37            }
38        }
39    }
40}
41
42impl From<JsonRpcErrorReason> for i32 {
43    fn from(reason: JsonRpcErrorReason) -> i32 {
44        match reason {
45            JsonRpcErrorReason::ParseError => PARSE_ERROR,
46            JsonRpcErrorReason::InvalidRequest => INVALID_REQUEST,
47            JsonRpcErrorReason::MethodNotFound => METHOD_NOT_FOUND,
48            JsonRpcErrorReason::InvalidParams => INVALID_PARAMS,
49            JsonRpcErrorReason::InternalError => INTERNAL_ERROR,
50            JsonRpcErrorReason::ServerError(code) | JsonRpcErrorReason::ApplicationError(code) => {
51                code
52            }
53        }
54    }
55}
56
57impl JsonRpcErrorReason {
58    fn new(code: i32) -> Self {
59        match code {
60            PARSE_ERROR => Self::ParseError,
61            INVALID_REQUEST => Self::InvalidRequest,
62            METHOD_NOT_FOUND => Self::MethodNotFound,
63            INVALID_PARAMS => Self::InvalidParams,
64            INTERNAL_ERROR => Self::InternalError,
65            -32099..=-32000 => Self::ServerError(code),
66            _ => Self::ApplicationError(code),
67        }
68    }
69}
70
71#[derive(Debug, Error, Clone, Serialize, Deserialize, PartialEq)]
72pub struct JsonRpcError {
73    code: i32,
74    message: String,
75    data: Value,
76}
77
78impl JsonRpcError {
79    pub fn new(code: JsonRpcErrorReason, message: String, data: Value) -> Self {
80        Self {
81            code: code.into(),
82            message,
83            data,
84        }
85    }
86}
87
88impl std::fmt::Display for JsonRpcError {
89    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90        write!(
91            f,
92            "{}: {}",
93            JsonRpcErrorReason::new(self.code),
94            self.message
95        )
96    }
97}
98
99#[cfg(feature = "anyhow_error")]
100impl From<anyhow::Error> for JsonRpcError {
101    fn from(error: anyhow::Error) -> Self {
102        let message = error.to_string();
103        let data = Value::default();
104        Self {
105            code: 1,
106            message,
107            data,
108        }
109    }
110}
111
112impl JsonRpcError {
113    pub fn error_reason(&self) -> JsonRpcErrorReason {
114        JsonRpcErrorReason::new(self.code)
115    }
116
117    pub fn code(&self) -> i32 {
118        self.code
119    }
120}