1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// Copyright 2022 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use std::{error, fmt, io, path::PathBuf};

/// Error `enum` containing variants for any errors that could potentially occur in this crate.
#[derive(Debug)]
pub enum Error {
    /// Error originating from the [`FlamegraphLayer`](crate::subscriber::layer::FlamegraphLayer).
    FlamegraphLayer(io::Error),
    /// Error originating from the [`Flamegrapher`](crate::util::Flamegrapher).
    Flamegrapher(FlamegrapherErrorKind),
    /// Error originating from the [`LogLayer`](crate::subscriber::layer::LogLayer).
    LogLayer(LogLayerErrorKind),
}

/// An error originating from the [`LogLayer`](crate::subscriber::layer::LogLayer).
#[derive(Debug)]
pub enum LogLayerErrorKind {
    /// Encountered an [`io::Error`].
    Io(io::Error),
    /// Error setting the default logger/subscriber.
    SetLogger(log::SetLoggerError),
}

impl fmt::Display for LogLayerErrorKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match &self {
            Self::Io(err) => write!(f, "{}", err),
            Self::SetLogger(err) => write!(f, "{}", err),
        }
    }
}

impl From<io::Error> for LogLayerErrorKind {
    fn from(err: io::Error) -> Self {
        Self::Io(err)
    }
}

impl From<log::SetLoggerError> for LogLayerErrorKind {
    fn from(err: log::SetLoggerError) -> Self {
        Self::SetLogger(err)
    }
}

/// An error originating from the [`FlamegraphLayer`](crate::subscriber::layer::FlamegraphLayer).
#[derive(Debug)]
pub enum FlamegraphLayerErrorKind {
    /// Encountered an [`io::Error`].
    Io(io::Error),
}

impl fmt::Display for FlamegraphLayerErrorKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match &self {
            Self::Io(err) => write!(f, "{}", err),
        }
    }
}

impl From<io::Error> for FlamegraphLayerErrorKind {
    fn from(err: io::Error) -> Self {
        Self::Io(err)
    }
}

/// An error originating from the [`Flamegrapher`](crate::util::Flamegrapher).
#[derive(Debug)]
pub enum FlamegrapherErrorKind {
    /// The provided graph file is invalid.
    GraphFileInvalid(PathBuf),
    /// Usage of [`inferno`] resulted in an error.
    Inferno(Box<dyn error::Error>),
    /// Encountered an [`io::Error`].
    Io(io::Error),
    /// The [`Flamegrapher`](crate::util::Flamegrapher) is missing a required field.
    MissingField(String),
    /// Could not find the provided folded stack file.
    StackFileNotFound(PathBuf),
}

impl fmt::Display for FlamegrapherErrorKind {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match &self {
            Self::GraphFileInvalid(path) => write!(
                f,
                "invalid flamegraph file path: directory {} does not exist",
                path.to_string_lossy()
            ),
            Self::Inferno(err) => write!(f, "{}", err),
            Self::Io(err) => write!(f, "{}", err),
            Self::MissingField(field) => write!(f, "flamegrapher builder missing field: {}", field),
            Self::StackFileNotFound(path) => write!(f, "folded stack file {} does not exist", path.to_string_lossy()),
        }
    }
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match &self {
            Self::FlamegraphLayer(err) => write!(f, "{}", err),
            Self::Flamegrapher(err) => write!(f, "{}", err),
            Self::LogLayer(err) => write!(f, "{}", err),
        }
    }
}

impl From<Box<dyn error::Error>> for FlamegrapherErrorKind {
    fn from(err: Box<dyn error::Error>) -> Self {
        Self::Inferno(err)
    }
}

impl From<io::Error> for FlamegrapherErrorKind {
    fn from(err: io::Error) -> Self {
        Self::Io(err)
    }
}

impl error::Error for Error {
    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
        match &self {
            Self::FlamegraphLayer(err) => Some(err),
            Self::Flamegrapher(FlamegrapherErrorKind::Io(err)) => Some(err),
            Self::LogLayer(LogLayerErrorKind::Io(err)) => Some(err),
            Self::LogLayer(LogLayerErrorKind::SetLogger(err)) => Some(err),
            _ => None,
        }
    }
}