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