mirror of
https://gitlab.com/fabinfra/fabaccess/bffh.git
synced 2024-11-25 16:17:56 +01:00
Better error wrapper type
This commit is contained in:
parent
7a0a50dc3f
commit
a79293add1
189
bffhd/error.rs
189
bffhd/error.rs
@ -1,116 +1,97 @@
|
|||||||
|
use miette::{Diagnostic, LabeledSpan, Severity, SourceCode};
|
||||||
|
use std::error;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
|
use std::io;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::db;
|
pub trait Description {
|
||||||
use rsasl::error::SessionError;
|
const DESCRIPTION: Option<&'static str> = None;
|
||||||
use std::any::TypeId;
|
const CODE: &'static str;
|
||||||
use std::error::Error as StdError;
|
const HELP: Option<&'static str> = None;
|
||||||
use std::fmt;
|
const URL: Option<&'static str> = None;
|
||||||
use std::fmt::Display;
|
|
||||||
use std::io;
|
|
||||||
|
|
||||||
use crate::resources::state::db::StateDBError;
|
|
||||||
use backtrace::{Backtrace, BacktraceFmt, PrintFmt};
|
|
||||||
use miette::{Diagnostic, LabeledSpan, Severity, SourceCode};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct TracedError<E: Diagnostic> {
|
|
||||||
pub inner: E,
|
|
||||||
pub backtrace: Backtrace,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Diagnostic> fmt::Display for TracedError<E> {
|
pub fn wrap<D: Description>(error: Source) -> Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
Error::new::<D>(error)
|
||||||
writeln!(f, "Error: {}", self.inner)?;
|
|
||||||
|
|
||||||
let cwd = std::env::current_dir();
|
|
||||||
let mut print_path =
|
|
||||||
move |fmt: &mut fmt::Formatter<'_>, path: backtrace::BytesOrWideString<'_>| {
|
|
||||||
let path = path.into_path_buf();
|
|
||||||
if let Ok(cwd) = &cwd {
|
|
||||||
if let Ok(suffix) = path.strip_prefix(cwd) {
|
|
||||||
return fmt::Display::fmt(&suffix.display(), fmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt::Display::fmt(&path.display(), fmt)
|
|
||||||
};
|
|
||||||
let mut bf = BacktraceFmt::new(f, PrintFmt::Short, &mut print_path);
|
|
||||||
bf.add_context()?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: 'static + Diagnostic> StdError for TracedError<E> {
|
|
||||||
fn source(&self) -> Option<&(dyn StdError + 'static)> {
|
|
||||||
self.inner.source()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: 'static + Diagnostic> Diagnostic for TracedError<E> {
|
|
||||||
#[inline(always)]
|
|
||||||
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
|
||||||
self.inner.code()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn severity(&self) -> Option<Severity> {
|
|
||||||
self.inner.severity()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
|
||||||
self.inner.help()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
|
||||||
self.inner.url()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn source_code(&self) -> Option<&dyn SourceCode> {
|
|
||||||
self.inner.source_code()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn labels(&self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + '_>> {
|
|
||||||
self.inner.labels()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
|
|
||||||
self.inner.related()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
fn diagnostic_source(&self) -> Option<&dyn Diagnostic> {
|
|
||||||
self.inner.diagnostic_source()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Error, Diagnostic)]
|
#[derive(Debug, Error, Diagnostic)]
|
||||||
/// Shared error type
|
pub enum Source {
|
||||||
pub enum BffhError {
|
#[error("io error occured")]
|
||||||
#[error("SASL error: {0:?}")]
|
Io(
|
||||||
SASL(SessionError),
|
#[source]
|
||||||
#[error("IO error: {0}")]
|
#[from]
|
||||||
IO(#[from] io::Error),
|
io::Error,
|
||||||
#[error("IO error: {0}")]
|
),
|
||||||
Boxed(#[from] Box<dyn std::error::Error>),
|
|
||||||
#[error("IO error: {0}")]
|
|
||||||
Capnp(#[from] capnp::Error),
|
|
||||||
#[error("IO error: {0}")]
|
|
||||||
DB(#[from] db::Error),
|
|
||||||
#[error("You do not have the permission required to do that.")]
|
|
||||||
Denied,
|
|
||||||
#[error("State DB operation failed")]
|
|
||||||
StateDB(#[from] StateDBError),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SessionError> for BffhError {
|
#[derive(Debug)]
|
||||||
fn from(e: SessionError) -> Self {
|
pub struct Error {
|
||||||
Self::SASL(e)
|
description: Option<&'static str>,
|
||||||
|
code: &'static str,
|
||||||
|
severity: Option<Severity>,
|
||||||
|
help: Option<&'static str>,
|
||||||
|
url: Option<&'static str>,
|
||||||
|
source: Source,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for Error {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
Display::fmt(&self.source, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, BffhError>;
|
impl error::Error for Error {
|
||||||
|
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||||
|
Some(&self.source)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn description(&self) -> &str {
|
||||||
|
if let Some(desc) = self.description {
|
||||||
|
desc
|
||||||
|
} else {
|
||||||
|
self.source.description()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
pub fn new<D: Description>(source: Source) -> Self {
|
||||||
|
Self {
|
||||||
|
description: D::DESCRIPTION,
|
||||||
|
code: D::CODE,
|
||||||
|
severity: source.severity(),
|
||||||
|
help: D::HELP,
|
||||||
|
url: D::URL,
|
||||||
|
source,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl miette::Diagnostic for Error {
|
||||||
|
fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||||
|
Some(Box::new(self.code))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn severity(&self) -> Option<Severity> {
|
||||||
|
self.severity
|
||||||
|
}
|
||||||
|
|
||||||
|
fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||||
|
self.help.map(|r| {
|
||||||
|
let b: Box<dyn Display + 'a> = Box::new(r);
|
||||||
|
b
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
|
||||||
|
self.url.map(|r| {
|
||||||
|
let b: Box<dyn Display + 'a> = Box::new(r);
|
||||||
|
b
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn diagnostic_source(&self) -> Option<&dyn Diagnostic> {
|
||||||
|
Some(&self.source)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -76,6 +76,11 @@ pub struct Diflouroborane {
|
|||||||
|
|
||||||
pub static RESOURCES: OnceCell<ResourcesHandle> = OnceCell::new();
|
pub static RESOURCES: OnceCell<ResourcesHandle> = OnceCell::new();
|
||||||
|
|
||||||
|
struct SignalHandlerErr;
|
||||||
|
impl error::Description for SignalHandlerErr {
|
||||||
|
const CODE: &'static str = "signals::new";
|
||||||
|
}
|
||||||
|
|
||||||
impl Diflouroborane {
|
impl Diflouroborane {
|
||||||
pub fn new(config: Config) -> miette::Result<Self> {
|
pub fn new(config: Config) -> miette::Result<Self> {
|
||||||
let mut server = logging::init(&config.logging);
|
let mut server = logging::init(&config.logging);
|
||||||
@ -140,8 +145,7 @@ impl Diflouroborane {
|
|||||||
pub fn run(&mut self) -> miette::Result<()> {
|
pub fn run(&mut self) -> miette::Result<()> {
|
||||||
let _guard = self.span.enter();
|
let _guard = self.span.enter();
|
||||||
let mut signals = signal_hook_async_std::Signals::new(&[SIGINT, SIGQUIT, SIGTERM])
|
let mut signals = signal_hook_async_std::Signals::new(&[SIGINT, SIGQUIT, SIGTERM])
|
||||||
.into_diagnostic()
|
.map_err(|ioerr| error::wrap::<SignalHandlerErr>(ioerr.into()))?;
|
||||||
.wrap_err("Failed to construct signal handler")?;
|
|
||||||
|
|
||||||
let sessionmanager = SessionManager::new(self.users.clone(), self.roles.clone());
|
let sessionmanager = SessionManager::new(self.users.clone(), self.roles.clone());
|
||||||
let authentication = AuthenticationHandle::new(self.users.clone());
|
let authentication = AuthenticationHandle::new(self.users.clone());
|
||||||
|
Loading…
Reference in New Issue
Block a user