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
64impl fmt::Display for SyslogErrCode
65{
66    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
67    {
68        match self
69        {
70            Self::OsError(error_kind) => 
71                write!(f, "[ErrorKind: {}]", error_kind),
72            Self::InternalError => 
73                write!(f, "[InternalError]"),
74            Self::SyslogThreadNotAvailable => 
75                write!(f, "[SyslogThreadNotAvailable]"),
76            Self::UnboundedChannelError => 
77                write!(f, "[UnboundedChannelError]"),
78            Self::MutexPoisoned => 
79                write!(f, "[MutexPoisoned]"),
80            Self::OsErrorErrno(errn) =>
81                write!(f, "[Errno: {}]", errn),
82            Self::Unusable => 
83                write!(f, "[Unusable]"),
84            Self::SendError =>
85                write!(f, "[SendError]"),
86            Self::NotAvail => 
87                write!(f, "[NotAvail]"),
88            Self::CoWWriteError => 
89                write!(f, "[CoWWriteError]"),
90            Self::CoWAlreadyLocked => 
91                write!(f, "[CoWAlreadyLocked]"),
92        }
93    }
94}
95
96impl SyslogErrCode
97{
98    pub 
99    fn get_os_err_code(&self) -> Option<ErrorKind>
100    {
101        match *self
102        {
103            Self::OsError(errn) => 
104                return Some(errn),
105            _ =>
106                return None,
107        }
108    }
109}
110
111/// A syslog crate error
112#[derive(Debug)]
113pub struct SyslogError 
114{
115    errcode: SyslogErrCode,
116    message: String,
117}
118
119impl SyslogError
120{
121    /// Creates new error
122    pub
123    fn new(errcode: SyslogErrCode, msg: String) -> Self
124    {
125        return SyslogError{errcode: errcode, message: msg};
126    }
127
128    /// Creates new error
129    pub
130    fn new_io(err: &std::io::Error, msg: String) -> Self
131    {
132        return SyslogError{errcode: SyslogErrCode::OsError(err.kind()), message: msg};
133    }
134
135    pub
136    fn new_errno(err: Errno, msg: String) -> Self
137    {
138        return SyslogError{errcode: SyslogErrCode::OsErrorErrno(err), message: msg};
139    }
140
141    /// Retuns a clone of [SyslogErrCode]
142    pub 
143    fn get_errcode(&self) -> SyslogErrCode
144    {
145        return self.errcode;
146    }
147
148    /// Moves out the error description
149    pub 
150    fn into_inner(self) -> String
151    {
152        return self.message;
153    }
154}
155
156impl fmt::Display for SyslogError 
157{
158    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result 
159    {
160        write!(f, "{} {}", self.errcode, self.message)
161    }
162}
163
164pub type SyRes<T> = Result<T, SyslogError>;
165
166#[macro_export]
167macro_rules! throw_error 
168{
169    ($($arg:tt)*) => (
170        return std::result::Result::Err($crate::error::SyslogError::new($crate::error::SyslogErrCode::InternalError, format!($($arg)*)))
171    )
172}
173
174#[macro_export]
175macro_rules! throw_error_os
176{
177    ($err:expr, $($arg:tt)*) => (
178        return std::result::Result::Err($crate::error::SyslogError::new_io(&$err, format!($($arg)*)))
179    )
180}
181
182#[macro_export]
183macro_rules! throw_error_errno
184{
185    ($errno:expr, $($arg:tt)*) => (
186        return std::result::Result::Err($crate::error::SyslogError::new_errno($errno, format!($($arg)*)))
187    )
188}
189
190#[macro_export]
191macro_rules! map_error 
192{
193    ($($arg:tt)*) => (
194        $crate::error::SyslogError::new($crate::error::SyslogErrCode::InternalError, format!($($arg)*))
195    )
196}
197
198#[macro_export]
199macro_rules! map_error_os
200{
201    ($err:expr, $($arg:tt)*) => (
202        $crate::error::SyslogError::new_io(&$err, format!($($arg)*))
203    )
204}
205
206#[macro_export]
207macro_rules! throw_error_code
208{
209    ($code:tt, $($arg:tt)*) => (
210        return std::result::Result::Err($crate::error::SyslogError::new($crate::error::SyslogErrCode::$code, format!($($arg)*)))
211    )
212}
213
214#[macro_export]
215macro_rules! map_error_code
216{
217    ($code:tt, $($arg:tt)*) => (
218        $crate::error::SyslogError::new($crate::error::SyslogErrCode::$code, format!($($arg)*))
219    )
220}