storefd/storefd-notify/src/error.rs
2024-01-12 09:53:38 +01:00

192 lines
5.8 KiB
Rust

//! Contains the error types used by the [`notify`](super) module.
#![allow(clippy::module_name_repetitions)]
use core::fmt::Display;
use std::error::Error;
use rustix::io::Errno;
#[derive(Debug)]
pub enum NewNotifierError {
InvalidAbstractSocket(Errno),
InvalidSocketPath(Errno),
CouldntOpenSocket(std::io::Error),
}
impl Display for NewNotifierError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
NewNotifierError::InvalidAbstractSocket(error) => {
write!(f, "couldn't open notify abstract socket: {error}")
}
NewNotifierError::InvalidSocketPath(error) => {
write!(f, "couldn't open notify socket from path: {error}")
}
NewNotifierError::CouldntOpenSocket(error) => {
write!(f, "couldn't open unix socket: {error}")
}
}
}
}
impl Error for NewNotifierError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
NewNotifierError::InvalidAbstractSocket(error)
| NewNotifierError::InvalidSocketPath(error) => Some(error),
NewNotifierError::CouldntOpenSocket(error) => Some(error),
}
}
}
#[derive(Debug)]
pub enum NotifyError {
SendMsg(Errno),
PushAncillaryMessage,
PartialSend,
}
impl Display for NotifyError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
NotifyError::SendMsg(error) => write!(f, "couldn't send the message: {error}"),
NotifyError::PushAncillaryMessage => {
f.write_str("couldn't push necessary ancillary message for fd passing")
}
NotifyError::PartialSend => f.write_str("only some of the message could be sent"),
}
}
}
impl Error for NotifyError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
NotifyError::SendMsg(error) => Some(error),
NotifyError::PushAncillaryMessage | NotifyError::PartialSend => None,
}
}
}
#[derive(Debug)]
pub enum FdNameError {
TooLong { length: usize, name: String },
NotAsciiNonControl { disallowed_char: char, name: String },
ContainColon(String),
}
impl Display for FdNameError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::TooLong { length, name } => write!(f, "the file descriptor name {name:?} is too long (is {length} characters and should be less than 255)"),
Self::NotAsciiNonControl { disallowed_char, name } => write!(f, "the file descriptor name {name:?} contains invalid character '{disallowed_char}' (only ASCII allowed)"),
Self::ContainColon(name) => write!(f, "the file descriptor name {name:?} contains a colon (':') which isn't allowed"),
}
}
}
impl Error for FdNameError {}
#[derive(Debug)]
pub enum StatusLineError {
TooManyLines,
}
impl Display for StatusLineError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::TooManyLines => {
f.write_str("The provided status line contains more than one line.")
}
}
}
}
impl Error for StatusLineError {}
#[derive(Debug)]
pub enum OtherStateError {
TooManyLines,
NoAssignement,
DisallowedState(String),
}
impl Display for OtherStateError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::DisallowedState(state) => write!(f, "The state assignement {state:?} isn't allowed."),
Self::NoAssignement => write!(f, "No assignement was found in provided custom state."),
Self::TooManyLines => write!(f, "States cannot contains newlines (they are newline separated in the underlying protocol).")
}
}
}
impl Error for OtherStateError {}
#[derive(Debug)]
pub enum BarrierError {
Notify(NotifyError),
FailedPipeCreation(Errno),
FailedPolling(Errno),
TimedOut,
}
impl From<NotifyError> for BarrierError {
fn from(value: NotifyError) -> Self {
Self::Notify(value)
}
}
impl Display for BarrierError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Notify(_) => write!(f, "Couldn't notify of barrier."),
Self::FailedPipeCreation(errno) => write!(
f,
"Couldn't create pipe to serve as a notify syncronisation barrier : error {errno}."
),
Self::FailedPolling(errno) => write!(f, "poll failed with error : {errno}."),
Self::TimedOut => write!(f, "Notification synchronisation timed out."),
}
}
}
impl Error for BarrierError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::Notify(source) => Some(source),
Self::FailedPipeCreation(source) | Self::FailedPolling(source) => Some(source),
Self::TimedOut => None,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum PollTimeoutFromIntError {
Negative,
}
impl Display for PollTimeoutFromIntError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Negative => write!(f, "This variant of BarrierTimeout cannot be negative but a negative number was passed.")
}
}
}
impl Error for PollTimeoutFromIntError {}
#[derive(Debug)]
pub enum MicrosecondsFromDurationError {
NoMicroseconds,
}
impl Display for MicrosecondsFromDurationError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::NoMicroseconds => write!(f, "Minimal precision is microseconds but no microseconds are within the Duration provided."),
}
}
}
impl Error for MicrosecondsFromDurationError {}