use crate::Error;
use serde::{Deserialize, Serialize};
use serde_json::{Value, json};
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub struct RpcError {
pub code: i64,
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub data: Option<Value>,
}
impl RpcError {
pub const CODE_PARSE_ERROR: i64 = -32700;
pub const CODE_INVALID_REQUEST: i64 = -32600;
pub const CODE_METHOD_NOT_FOUND: i64 = -32601;
pub const CODE_INVALID_PARAMS: i64 = -32602;
pub const CODE_INTERNAL_ERROR: i64 = -32603;
pub fn from_parse_error(data: Option<Value>) -> Self {
Self {
code: Self::CODE_PARSE_ERROR,
message: "Parse error".to_string(),
data,
}
}
pub fn from_invalid_request(data: Option<Value>) -> Self {
Self {
code: Self::CODE_INVALID_REQUEST,
message: "Invalid Request".to_string(),
data,
}
}
pub fn from_method_not_found(data: Option<Value>) -> Self {
Self {
code: Self::CODE_METHOD_NOT_FOUND,
message: "Method not found".to_string(),
data,
}
}
pub fn from_invalid_params(data: Option<Value>) -> Self {
Self {
code: Self::CODE_INVALID_PARAMS,
message: "Invalid params".to_string(),
data,
}
}
pub fn from_internal_error(data: Option<Value>) -> Self {
Self {
code: Self::CODE_INTERNAL_ERROR,
message: "Internal error".to_string(),
data,
}
}
fn new(code: i64, message: impl Into<String>, error: Option<&dyn std::error::Error>) -> Self {
let data = error.map(|e| json!(e.to_string()));
Self {
code,
message: message.into(),
data,
}
}
}
impl From<&Error> for RpcError {
fn from(err: &Error) -> Self {
match err {
Error::ParamsParsing(p) => Self::new(Self::CODE_INVALID_PARAMS, "Invalid params", Some(p)),
Error::ParamsMissingButRequested => Self::new(Self::CODE_INVALID_PARAMS, "Invalid params", Some(err)),
Error::MethodUnknown => Self::new(Self::CODE_METHOD_NOT_FOUND, "Method not found", Some(err)),
Error::FromResources(fr_err) => Self::new(Self::CODE_INTERNAL_ERROR, "Internal error", Some(fr_err)),
Error::HandlerResultSerialize(s_err) => Self::new(Self::CODE_INTERNAL_ERROR, "Internal error", Some(s_err)),
Error::Handler(h_err) => Self::new(Self::CODE_INTERNAL_ERROR, "Internal error", Some(h_err)),
}
}
}
impl From<crate::CallError> for RpcError {
fn from(call_error: crate::CallError) -> Self {
RpcError::from(&call_error.error)
}
}
impl From<&crate::CallError> for RpcError {
fn from(call_error: &crate::CallError) -> Self {
RpcError::from(&call_error.error)
}
}