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