shinyframework_common 0.1.2

Shiny Common
Documentation
use std::borrow::Cow;
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
use std::panic::Location;
use crate::pointer_utils::ToBox;

#[derive(Debug)]
pub struct ServiceError {
    trace: ErrorTrace,
    kind: ServiceErrorKind,
    source: Option<Box<dyn Error + Send>>,
}

impl Display for ServiceError {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match &self.kind {
            ServiceErrorKind::InternalError { code } => {
                write!(f, "internal error [error_code = `{code}`]")?;
            }
            ServiceErrorKind::DependencyError { dependency_name, code, } => {
                write!(f, "dependency error [dependency_name = `{dependency_name}`] [error_code = `{code}`]")?;
            }
        };

        Ok(())
    }
}

impl Error for ServiceError {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        match &self.source {
            None => { None }
            Some(err) => { Some(&**err) }
        }
    }
}

impl ServiceError {
    pub fn internal_error(
        code: Cow<'static, str>,
        source: Option<Box<dyn Error + Send>>,
        trace: ErrorTrace,
    ) -> ServiceError {
        ServiceError {
            trace,
            source,
            kind: ServiceErrorKind::InternalError { code },
        }
    }

    pub fn dependency_error(
        dependency_name: Cow<'static, str>,
        code: Cow<'static, str>,
        source: Option<Box<dyn Error + Send>>,
        trace: ErrorTrace,
    ) -> ServiceError {
        ServiceError {
            trace,
            source,
            kind: ServiceErrorKind::DependencyError {
                code,
                dependency_name,
            },
        }
    }

    pub fn set_error<T>(&mut self, error: T)
        where T: Error + Send + 'static
    {
        self.source = Some(error.boxed())
    }

    pub fn with_error<T>(mut self, error: T) -> ServiceError
        where T: Error + Send + 'static
    {
        self.set_error(error);
        self
    }

    pub fn trace(&self) -> &ErrorTrace {
        &self.trace
    }
}

#[derive(Debug)]
enum ServiceErrorKind {
    InternalError {
        code: Cow<'static, str>,
    },
    DependencyError {
        code: Cow<'static, str>,
        dependency_name: Cow<'static, str>,
    },
}

#[derive(Debug)]
pub enum ErrorTrace {
    // Backtrace(Backtrace),
    Location(&'static Location<'static>),
}