timber_rust/service/
serror.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright 2026 Dante Doménech Martinez dante19031999@gmail.com
3
4use std::fmt;
5use std::fmt::{Debug, Display, Formatter};
6
7/// Represents an error returned by a remote HTTP service.
8///
9/// This struct specifically captures failures where the connection was successful,
10/// but the server returned a non-success status code (e.g., 4xx or 5xx).
11///
12/// ### Feature Requirement
13/// This type is only available when the **`network`** feature is enabled in your `Cargo.toml`.
14///
15/// ### Common Scenarios
16/// - **429 Too Many Requests**: Rate limiting is active.
17/// - **400 Bad Request**: Often indicates "Out of Order" entries in service like Loki.
18/// - **503 Service Unavailable**: The remote logging endpoint is temporarily down.
19#[cfg(feature = "network")]
20pub struct HttpError {
21    /// The 3-digit HTTP response status code.
22    status_code: u16,
23}
24
25#[cfg(feature = "network")]
26impl HttpError {
27    /// Creates a new [`HttpError`] from a raw status code.
28    ///
29    /// # Parameters
30    /// - `status_code`: The [u16] representation of the HTTP response (e.g., 404).
31    ///
32    /// # Example
33    /// ```ignore
34    /// // Requires: cargo test --features network
35    /// let error = HttpError::new(429);
36    /// assert_eq!(error.status_code(), 429);
37    /// ```
38    pub fn new(status_code: u16) -> HttpError {
39        HttpError { status_code }
40    }
41
42    /// Returns the HTTP status code associated with this error.
43    ///
44    /// This is useful in `fallback` logic to determine if the error
45    /// is recoverable or if it requires a specific alerting path.
46    pub fn status_code(&self) -> u16 {
47        self.status_code
48    }
49}
50
51#[cfg(feature = "network")]
52impl Debug for HttpError {
53    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
54        write!(f, "Http error: {}", self.status_code)
55    }
56}
57
58#[cfg(feature = "network")]
59impl Display for HttpError {
60    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
61        write!(f, "Http error: {}", self.status_code)
62    }
63}
64
65#[cfg(feature = "network")]
66impl std::error::Error for HttpError {}
67
68/// An error indicating that a requested functionality is unavailable because its
69/// corresponding crate feature was not enabled at compile time.
70///
71/// This error typically occurs when a configuration file attempts to use a service
72/// (like a network logger) in a build that was optimized for local-use only.
73///
74/// ### How to resolve
75/// If you encounter this error, ensure the required feature is enabled in your `Cargo.toml`:
76/// ```toml
77/// [dependencies]
78/// my_logger = { version = "Your version here", features = ["Feature name here"] }
79/// ```
80pub struct FeatureDisabledError {
81    name: String,
82}
83
84impl FeatureDisabledError {
85    /// Creates a new error instance for the specified feature name.
86    ///
87    /// # Example
88    /// ```
89    /// # use timber_rust::service::FeatureDisabledError;
90    /// let err = FeatureDisabledError::new("loki".to_string());
91    /// ```
92    pub fn new(name: String) -> Self {
93        FeatureDisabledError { name }
94    }
95
96    /// Returns the name of the feature that caused the error.
97    ///
98    /// This can be used to programmatically decide whether to fallback
99    /// to a different service.
100    pub fn name(&self) -> &str {
101        self.name.as_str()
102    }
103}
104
105impl Debug for FeatureDisabledError {
106    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
107        // Debug output often used for developer logs
108        write!(f, "FeatureDisabledError: '{}' is not compiled into this binary", self.name)
109    }
110}
111
112impl Display for FeatureDisabledError {
113    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
114        // User-friendly message
115        write!(f, "The feature '{}' is currently disabled. Please recompile with the appropriate feature flag.", self.name)
116    }
117}
118
119impl std::error::Error for FeatureDisabledError {}