Skip to main content

mago_reporting/
error.rs

1//! Error types for the reporting crate.
2//!
3//! This module defines the error types that can occur during issue reporting,
4//! including database errors, JSON serialization errors, file I/O errors,
5//! and invalid configuration errors.
6
7use codespan_reporting::files::Error as FilesError;
8use serde_json::Error as JsonError;
9use std::io::Error as IoError;
10
11use mago_database::error::DatabaseError;
12
13/// Errors that can occur during issue reporting.
14#[derive(Debug)]
15pub enum ReportingError {
16    /// An error occurred while accessing the database.
17    DatabaseError(DatabaseError),
18    /// An error occurred while serializing or deserializing JSON.
19    JsonError(JsonError),
20    /// An error occurred while accessing source files.
21    FilesError(FilesError),
22    /// An I/O error occurred.
23    IoError(IoError),
24    /// An invalid reporting target was specified.
25    InvalidTarget(String),
26    /// An invalid reporting format was specified.
27    InvalidFormat(String),
28}
29
30impl ReportingError {
31    #[must_use]
32    pub fn is_broken_pipe(&self) -> bool {
33        let err = match self {
34            Self::IoError(err) => err,
35            Self::FilesError(FilesError::Io(err)) => err,
36            _ => return false,
37        };
38
39        err.raw_os_error() == Some(32) || err.kind() == std::io::ErrorKind::BrokenPipe
40    }
41}
42
43impl std::fmt::Display for ReportingError {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        match self {
46            Self::DatabaseError(error) => write!(f, "{error}"),
47            Self::JsonError(error) => write!(f, "Json error: {error}"),
48            Self::FilesError(error) => write!(f, "Files error: {error}"),
49            Self::IoError(error) => write!(f, "IO error: {error}"),
50            Self::InvalidTarget(target) => write!(f, "Invalid target: {target}"),
51            Self::InvalidFormat(format) => write!(f, "Invalid format: {format}"),
52        }
53    }
54}
55
56impl std::error::Error for ReportingError {
57    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
58        match self {
59            Self::DatabaseError(error) => Some(error),
60            Self::JsonError(error) => Some(error),
61            Self::FilesError(error) => Some(error),
62            Self::IoError(error) => Some(error),
63            Self::InvalidTarget(_) => None,
64            Self::InvalidFormat(_) => None,
65        }
66    }
67}
68
69impl From<DatabaseError> for ReportingError {
70    fn from(error: DatabaseError) -> Self {
71        Self::DatabaseError(error)
72    }
73}
74
75impl From<JsonError> for ReportingError {
76    fn from(error: JsonError) -> Self {
77        Self::JsonError(error)
78    }
79}
80
81impl From<FilesError> for ReportingError {
82    fn from(error: FilesError) -> Self {
83        Self::FilesError(error)
84    }
85}
86
87impl From<IoError> for ReportingError {
88    fn from(error: IoError) -> Self {
89        Self::IoError(error)
90    }
91}