syslog_rs/
error.rs

1/*-
2 * syslog-rs - a syslog client translated from libc to rust
3 * 
4 * Copyright 2025 Aleksandr Morozov
5 * 
6 * The syslog-rs crate can be redistributed and/or modified
7 * under the terms of either of the following licenses:
8 *
9 *   1. the Mozilla Public License Version 2.0 (the “MPL”) OR
10 *
11 *   2. The MIT License (MIT)
12 *                     
13 *   3. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
14 */
15
16
17use std::{fmt, io::ErrorKind};
18
19#[cfg(target_family = "unix")]
20use nix::errno::Errno;
21
22/// Error code
23#[derive(Clone, Copy, Debug, PartialEq, Eq)]
24pub enum SyslogErrCode
25{
26    /// Os Error
27    OsError(ErrorKind),
28
29    /// Os Error
30    #[cfg(target_family = "unix")]
31    OsErrorErrno(Errno),
32
33    #[cfg(target_family = "windows")]
34    OsErrorErrno(i32),
35
36    /// A message which can be output to stderr
37    InternalError,
38
39    /// Only for syslog_sync_queue.rs and returned only when syslog thread is stopped
40    /// and someone is trying to do some operation
41    SyslogThreadNotAvailable,
42
43    /// Only for syslog_sync_queue.rs and returned only when syslog thread is failed
44    /// to send back data
45    UnboundedChannelError,
46
47    /// Mutex poisoned, can not contunue
48    MutexPoisoned,
49
50    /// The function is not usable.
51    Unusable,
52
53    /// Channel errors during transmission.
54    SendError,
55
56    /// Functionality os not available.
57    NotAvail,
58
59    /// General error which identifies problems writing back newly copied value.
60    /// 
61    /// This error should not be rised when using RwLocked CoW, but atomic may.
62    CoWWriteError,
63
64    /// Is returned warning that the instance is already exclusivly copied to be written
65    /// in neares future, so other thread can `read` or `try_read`.
66    CoWAlreadyLocked,
67
68    /// [libc::ENOBUFS] scenario 2, not enoughspace
69    UnixNotEnoughSpace,
70}
71
72impl fmt::Display for SyslogErrCode
73{
74    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
75    {
76        match self
77        {
78            Self::OsError(error_kind) => 
79                write!(f, "[ErrorKind: {}]", error_kind),
80            Self::InternalError => 
81                write!(f, "[InternalError]"),
82            Self::SyslogThreadNotAvailable => 
83                write!(f, "[SyslogThreadNotAvailable]"),
84            Self::UnboundedChannelError => 
85                write!(f, "[UnboundedChannelError]"),
86            Self::MutexPoisoned => 
87                write!(f, "[MutexPoisoned]"),
88            Self::OsErrorErrno(errn) =>
89                write!(f, "[Errno: {}]", errn),
90            Self::Unusable => 
91                write!(f, "[Unusable]"),
92            Self::SendError =>
93                write!(f, "[SendError]"),
94            Self::NotAvail => 
95                write!(f, "[NotAvail]"),
96            Self::CoWWriteError => 
97                write!(f, "[CoWWriteError]"),
98            Self::CoWAlreadyLocked => 
99                write!(f, "[CoWAlreadyLocked]"),
100            Self::UnixNotEnoughSpace => 
101                write!(f, "[UnixNotEnoughSpace(ENOBUFS)]")
102        }
103    }
104}
105
106impl SyslogErrCode
107{
108    pub 
109    fn get_os_err_code(&self) -> Option<ErrorKind>
110    {
111        match *self
112        {
113            Self::OsError(errn) => 
114                return Some(errn),
115            _ =>
116                return None,
117        }
118    }
119}
120
121/// A syslog crate error
122#[derive(Debug)]
123pub struct SyslogError 
124{
125    errcode: SyslogErrCode,
126    message: String,
127}
128
129impl SyslogError
130{
131    /// Creates new error
132    pub
133    fn new(errcode: SyslogErrCode, msg: String) -> Self
134    {
135        return SyslogError{errcode: errcode, message: msg};
136    }
137
138    /// Creates new error
139    pub
140    fn new_io(err: &std::io::Error, msg: String) -> Self
141    {
142        return SyslogError{errcode: SyslogErrCode::OsError(err.kind()), message: msg};
143    }
144
145    #[cfg(target_family = "unix")]
146    pub
147    fn new_errno(err: Errno, msg: String) -> Self
148    {
149        return SyslogError{errcode: SyslogErrCode::OsErrorErrno(err), message: msg};
150    }
151
152    #[cfg(target_family = "windows")]
153    pub
154    fn new_errno(err: i32, msg: String) -> Self
155    {
156        return SyslogError{errcode: SyslogErrCode::OsErrorErrno(err), message: msg};
157    }
158
159    /// Retuns a clone of [SyslogErrCode]
160    pub 
161    fn get_errcode(&self) -> SyslogErrCode
162    {
163        return self.errcode;
164    }
165
166    /// Moves out the error description
167    pub 
168    fn into_inner(self) -> String
169    {
170        return self.message;
171    }
172}
173
174impl fmt::Display for SyslogError 
175{
176    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result 
177    {
178        write!(f, "{} {}", self.errcode, self.message)
179    }
180}
181
182pub type SyRes<T> = Result<T, SyslogError>;
183
184#[macro_export]
185macro_rules! throw_error 
186{
187    ($($arg:tt)*) => (
188        return std::result::Result::Err($crate::error::SyslogError::new($crate::error::SyslogErrCode::InternalError, format!($($arg)*)))
189    )
190}
191
192#[macro_export]
193macro_rules! throw_error_os
194{
195    ($err:expr, $($arg:tt)*) => (
196        return std::result::Result::Err($crate::error::SyslogError::new_io(&$err, format!($($arg)*)))
197    )
198}
199
200#[macro_export]
201macro_rules! throw_error_errno
202{
203    ($errno:expr, $($arg:tt)*) => (
204        return std::result::Result::Err($crate::error::SyslogError::new_errno($errno, format!($($arg)*)))
205    )
206}
207
208#[macro_export]
209macro_rules! map_error 
210{
211    ($($arg:tt)*) => (
212        $crate::error::SyslogError::new($crate::error::SyslogErrCode::InternalError, format!($($arg)*))
213    )
214}
215
216#[macro_export]
217macro_rules! map_error_os
218{
219    ($err:expr, $($arg:tt)*) => (
220        $crate::error::SyslogError::new_io(&$err, format!($($arg)*))
221    )
222}
223
224#[macro_export]
225macro_rules! throw_error_code
226{
227    ($code:tt, $($arg:tt)*) => (
228        return std::result::Result::Err($crate::error::SyslogError::new($crate::error::SyslogErrCode::$code, format!($($arg)*)))
229    )
230}
231
232#[macro_export]
233macro_rules! map_error_code
234{
235    ($code:tt, $($arg:tt)*) => (
236        $crate::error::SyslogError::new($crate::error::SyslogErrCode::$code, format!($($arg)*))
237    )
238}