Newer
Older
use serde::{Deserialize, Serialize};
Niklas Adolfsson
committed
use serde_json::value::RawValue;
/// Convenience type for displaying errors.
#[derive(Clone, Debug, PartialEq)]
pub struct Mismatch<T> {
/// Expected value.
pub expected: T,
/// Actual value.
pub got: T,
}
impl<T: fmt::Display> fmt::Display for Mismatch<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_fmt(format_args!("Expected: {}, Got: {}", self.expected, self.got))
}
}
/// Error that occurs when a call failed.
#[derive(Debug, thiserror::Error)]
pub enum CallError {
/// Invalid params in the call.
Niklas Adolfsson
committed
#[error("Invalid params in the call")]
Niklas Adolfsson
committed
/// The call failed (let jsonrpsee assign default error code and error message).
#[error("RPC Call failed: {0}")]
Niklas Adolfsson
committed
Failed(Box<dyn std::error::Error + Send + Sync>),
/// Custom error with specific JSON-RPC error code, message and data.
#[error("RPC Call failed: code: {code}, message: {message}, data: {data:?}")]
Custom {
/// JSON-RPC error code
code: i32,
/// Short description of the error.
message: String,
/// A primitive or structured value that contains additional information about the error.
data: Option<Box<RawValue>>,
},
/// Error type.
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// Error that occurs when a call failed.
#[error("Server call failed: {0}")]
/// Networking error or error on the low-level protocol layer.
#[error("Networking or low-level protocol error: {0}")]
Transport(#[source] Box<dyn std::error::Error + Send + Sync>),
/// JSON-RPC request error.
#[error("JSON-RPC request error: {0:?}")]
Request(String),
/// Frontend/backend channel error.
#[error("Frontend/backend channel error: {0}")]
Internal(#[from] futures_channel::mpsc::SendError),
/// Invalid response,
#[error("Invalid response: {0}")]
InvalidResponse(Mismatch<String>),
/// The background task has been terminated.
#[error("The background task been terminated because: {0}; restart required")]
RestartNeeded(String),
/// Failed to parse the data.
ParseError(#[from] serde_json::Error),
/// Invalid subscription ID.
#[error("Invalid subscription ID")]
InvalidSubscriptionId,
/// Invalid request ID.
#[error("Invalid request ID")]
InvalidRequestId,
/// Client received a notification with an unregistered method
#[error("Unregistered notification method")]
UnregisteredNotification(String),
/// A request with the same request ID has already been registered.
#[error("A request with the same request ID has already been registered")]
DuplicateRequestId,
/// Method was already registered.
#[error("Method: {0} was already registered")]
MethodAlreadyRegistered(String),
/// Method with that name has not yet been registered.
#[error("Method: {0} has not yet been registered")]
MethodNotFound(String),
/// Subscribe and unsubscribe method names are the same.
#[error("Cannot use the same method name for subscribe and unsubscribe, used: {0}")]
/// Subscription got closed.
#[error("Subscription closed: {0:?}")]
SubscriptionClosed(SubscriptionClosedError),
/// Request timeout
#[error("Request timeout")]
RequestTimeout,
/// Configured max number of request slots exceeded.
#[error("Configured max number of request slots exceeded")]
MaxSlotsExceeded,
/// Attempted to stop server that is already stopped.
#[error("Attempted to stop server that is already stopped")]
AlreadyStopped,
/// List passed into `set_allowed_origins` was empty
#[error("Must set at least one allowed value for the {0} header")]
EmptyAllowList(&'static str),
/// Error type with a special `subscription_closed` field to detect that
/// a subscription has been closed to distinguish valid items produced
/// by the server on the subscription stream from an error.
#[derive(Deserialize, Serialize, Debug)]
pub struct SubscriptionClosedError {
subscription_closed: String,
}
impl From<String> for SubscriptionClosedError {
fn from(msg: String) -> Self {
Self { subscription_closed: msg }
}
}
/// Generic transport error.
#[derive(Debug, thiserror::Error)]
pub enum GenericTransportError<T: std::error::Error + Send + Sync> {
/// Request was too large.
#[error("The request was too big")]
TooLarge,
/// Concrete transport error.
#[error("Transport error: {0}")]
Inner(T),
}
impl From<std::io::Error> for Error {
fn from(io_err: std::io::Error) -> Error {
Error::Transport(Box::new(io_err))
}
}
impl From<soketto::handshake::Error> for Error {
fn from(handshake_err: soketto::handshake::Error) -> Error {
Error::Transport(Box::new(handshake_err))
}
}
impl From<soketto::connection::Error> for Error {
fn from(conn_err: soketto::connection::Error) -> Error {
Error::Transport(Box::new(conn_err))
}
}
impl From<hyper::Error> for Error {
fn from(hyper_err: hyper::Error) -> Error {
Error::Transport(Box::new(hyper_err))
}
}