use std::convert::Infallible;
use prost::DecodeError;
use thiserror::Error as ThisError;
use tracing::{error, warn};
#[derive(Debug, ThisError)]
pub enum Error {
#[error("No handlers were registered on the app.")]
NoHandlers,
#[error("Consumer cancelled on routing key {0}")]
ConsumerCancelled(String),
#[error("An underlying `lapin` call failed: {0}")]
Lapin(lapin::Error),
}
#[derive(Debug, ThisError)]
pub enum HandlerError {
#[error("Invalid Request: {0:#}")]
InvalidRequest(RequestError),
}
#[derive(Debug, ThisError)]
pub enum RequestError {
#[error("Message could not be decoded into the required type: {0:#}")]
DecodeError(DecodeError),
}
pub trait FromError<Err> {
fn from_error(error: Err) -> Self;
}
impl<T> FromError<Infallible> for T {
fn from_error(error: Infallible) -> Self {
match error {}
}
}
impl<T> FromError<HandlerError> for Option<T>
where
T: FromError<HandlerError>,
{
fn from_error(error: HandlerError) -> Self {
Some(FromError::from_error(error))
}
}
impl From<DecodeError> for HandlerError {
fn from(e: DecodeError) -> Self {
HandlerError::InvalidRequest(RequestError::DecodeError(e))
}
}
impl FromError<HandlerError> for () {
fn from_error(error: HandlerError) -> Self {
match error {
HandlerError::InvalidRequest(e) => {
warn!("Listener handler received an invalid request: {e:#}")
}
}
}
}