syslog_rs/
error.rs

1/*-
2 * syslog-rs - a syslog client translated from libc to rust
3 * 
4 * Copyright 2025 Aleksandr Morozov
5 * 
6 * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by
7 * the European Commission - subsequent versions of the EUPL (the "Licence").
8 * 
9 * You may not use this work except in compliance with the Licence.
10 * 
11 * You may obtain a copy of the Licence at:
12 * 
13 *    https://joinup.ec.europa.eu/software/page/eupl
14 * 
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the Licence is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18 * Licence for the specific language governing permissions and limitations
19 * under the Licence.
20 */
21
22
23use std::{fmt, io::ErrorKind};
24
25use nix::errno::Errno;
26
27/// Error code
28#[derive(Clone, Copy, Debug, PartialEq, Eq)]
29pub enum SyslogErrCode
30{
31    /// Os Error
32    OsError(ErrorKind),
33
34    /// Os Error
35    OsErrorErrno(Errno),
36
37    /// A message which can be output to stderr
38    InternalError,
39
40    /// Only for syslog_sync_queue.rs and returned only when syslog thread is stopped
41    /// and someone is trying to do some operation
42    SyslogThreadNotAvailable,
43
44    /// Only for syslog_sync_queue.rs and returned only when syslog thread is failed
45    /// to send back data
46    UnboundedChannelError,
47
48    /// Mutex poisoned, can not contunue
49    MutexPoisoned,
50
51    /// The function is not usable.
52    Unusable,
53
54    SendError,
55
56    SoftAssertionTrap,
57}
58
59impl fmt::Display for SyslogErrCode
60{
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result 
62    {
63        match self
64        {
65            Self::OsError(error_kind) => 
66                write!(f, "[ErrorKind: {}]", error_kind),
67            Self::InternalError => 
68                write!(f, "[InternalError]"),
69            Self::SyslogThreadNotAvailable => 
70                write!(f, "[SyslogThreadNotAvailable]"),
71            Self::UnboundedChannelError => 
72                write!(f, "[UnboundedChannelError]"),
73            Self::MutexPoisoned => 
74                write!(f, "[MutexPoisoned]"),
75            Self::OsErrorErrno(errn) =>
76                write!(f, "[Errno: {}]", errn),
77            Self::Unusable => 
78                write!(f, "[Unusable]"),
79            Self::SendError =>
80                write!(f, "[SendError]"),
81            Self::SoftAssertionTrap => 
82                write!(f, "[SoftAssertionTrap]"),
83        }
84    }
85}
86
87impl SyslogErrCode
88{
89    pub 
90    fn get_os_err_code(&self) -> Option<ErrorKind>
91    {
92        match *self
93        {
94            Self::OsError(errn) => 
95                return Some(errn),
96            _ =>
97                return None,
98        }
99    }
100}
101
102/// A syslog crate error
103#[derive(Debug)]
104pub struct SyslogError 
105{
106    errcode: SyslogErrCode,
107    message: String,
108}
109
110impl SyslogError
111{
112    /// Creates new error
113    pub(crate)
114    fn new(errcode: SyslogErrCode, msg: String) -> Self
115    {
116        return SyslogError{errcode: errcode, message: msg};
117    }
118
119    /// Creates new error
120    pub(crate)
121    fn new_io(err: &std::io::Error, msg: String) -> Self
122    {
123        return SyslogError{errcode: SyslogErrCode::OsError(err.kind()), message: msg};
124    }
125
126    pub(crate)
127    fn new_errno(err: Errno, msg: String) -> Self
128    {
129        return SyslogError{errcode: SyslogErrCode::OsErrorErrno(err), message: msg};
130    }
131
132    /// Retuns a clone of [SyslogErrCode]
133    pub 
134    fn get_errcode(&self) -> SyslogErrCode
135    {
136        return self.errcode;
137    }
138
139    /// Moves out the error description
140    pub 
141    fn into_inner(self) -> String
142    {
143        return self.message;
144    }
145}
146
147impl fmt::Display for SyslogError 
148{
149    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result 
150    {
151        write!(f, "{} {}", self.errcode, self.message)
152    }
153}
154
155pub type SyRes<T> = Result<T, SyslogError>;
156
157#[macro_export]
158macro_rules! throw_error 
159{
160    ($($arg:tt)*) => (
161        return std::result::Result::Err(crate::error::SyslogError::new(crate::error::SyslogErrCode::InternalError, format!($($arg)*)))
162    )
163}
164
165#[macro_export]
166macro_rules! throw_error_os
167{
168    ($err:expr, $($arg:tt)*) => (
169        return std::result::Result::Err(crate::error::SyslogError::new_io(&$err, format!($($arg)*)))
170    )
171}
172
173#[macro_export]
174macro_rules! throw_error_errno
175{
176    ($errno:expr, $($arg:tt)*) => (
177        return std::result::Result::Err(crate::error::SyslogError::new_errno($errno, format!($($arg)*)))
178    )
179}
180
181#[macro_export]
182macro_rules! map_error 
183{
184    ($($arg:tt)*) => (
185        crate::error::SyslogError::new(crate::error::SyslogErrCode::InternalError, format!($($arg)*))
186    )
187}
188
189#[macro_export]
190macro_rules! map_error_os
191{
192    ($err:expr, $($arg:tt)*) => (
193        crate::error::SyslogError::new_io(&$err, format!($($arg)*))
194    )
195}
196
197#[macro_export]
198macro_rules! throw_error_code
199{
200    ($code:tt, $($arg:tt)*) => (
201        return std::result::Result::Err(crate::error::SyslogError::new(crate::error::SyslogErrCode::$code, format!($($arg)*)))
202    )
203}
204
205#[macro_export]
206macro_rules! map_error_code
207{
208    ($code:tt, $($arg:tt)*) => (
209        crate::error::SyslogError::new(crate::error::SyslogErrCode::$code, format!($($arg)*))
210    )
211}