allure_core/
error.rs

1//! Error types for Allure operations.
2//!
3//! This module provides a unified error type for all Allure operations,
4//! including I/O errors, serialization errors, and configuration issues.
5
6use thiserror::Error;
7
8/// Result type alias for Allure operations.
9pub type AllureResult<T> = Result<T, AllureError>;
10
11/// Errors that can occur during Allure operations.
12#[derive(Debug, Error)]
13#[non_exhaustive]
14pub enum AllureError {
15    /// I/O error occurred while reading or writing files.
16    #[error("I/O error: {0}")]
17    Io(#[from] std::io::Error),
18
19    /// JSON serialization or deserialization error.
20    #[error("Serialization error: {0}")]
21    Serialization(#[from] serde_json::Error),
22
23    /// Configuration error with a descriptive message.
24    #[error("Configuration error: {0}")]
25    Configuration(String),
26
27    /// No active test context is available.
28    ///
29    /// This error occurs when trying to add metadata or steps
30    /// outside of a test function wrapped with `#[allure_test]`.
31    #[error("No active test context - ensure you are inside an #[allure_test] function")]
32    NoActiveContext,
33
34    /// Invalid attachment error.
35    #[error("Invalid attachment: {0}")]
36    InvalidAttachment(String),
37
38    /// Invalid parameter value.
39    #[error("Invalid parameter: {0}")]
40    InvalidParameter(String),
41}
42
43impl AllureError {
44    /// Creates a new configuration error.
45    pub fn configuration(message: impl Into<String>) -> Self {
46        AllureError::Configuration(message.into())
47    }
48
49    /// Creates a new invalid attachment error.
50    pub fn invalid_attachment(message: impl Into<String>) -> Self {
51        AllureError::InvalidAttachment(message.into())
52    }
53
54    /// Creates a new invalid parameter error.
55    pub fn invalid_parameter(message: impl Into<String>) -> Self {
56        AllureError::InvalidParameter(message.into())
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn test_error_display() {
66        let io_err = AllureError::Io(std::io::Error::new(
67            std::io::ErrorKind::NotFound,
68            "file not found",
69        ));
70        assert!(io_err.to_string().contains("I/O error"));
71
72        let config_err = AllureError::configuration("invalid path");
73        assert_eq!(config_err.to_string(), "Configuration error: invalid path");
74
75        let no_context = AllureError::NoActiveContext;
76        assert!(no_context.to_string().contains("No active test context"));
77    }
78
79    #[test]
80    fn test_error_from_io() {
81        let io_err = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "access denied");
82        let allure_err: AllureError = io_err.into();
83        assert!(matches!(allure_err, AllureError::Io(_)));
84    }
85
86    #[test]
87    fn test_error_constructors() {
88        let attach_err = AllureError::invalid_attachment("file too large");
89        assert!(matches!(attach_err, AllureError::InvalidAttachment(_)));
90
91        let param_err = AllureError::invalid_parameter("empty name");
92        assert!(matches!(param_err, AllureError::InvalidParameter(_)));
93    }
94}