rnotifylib/send_error/
mod.rs

1use std::error::Error;
2use std::fmt::{Display, Formatter};
3use crate::message::author::Author;
4use crate::message::{Level, Message, MessageDetail};
5use crate::send_error::reported::ReportedSendError;
6
7pub mod borrowed;
8pub mod owned;
9pub mod reported;
10
11pub trait SendError {
12    fn get_error(&self) -> &Box<dyn Error>;
13
14    fn get_failed_destination_id(&self) -> &str;
15
16    fn get_failed_message(&self) -> &Message;
17
18    fn create_report_message(&self) -> Message {
19        Message::new(Level::SelfError,
20                     Some(format!("Failed to send notification to destination {}", self.get_failed_destination_id())),
21                     MessageDetail::Raw(format!("Rnotify failed to send a message {:?} to destination id '{}'. Error: '{}' A notification has been sent here because this is configured as a root logger.",
22                                                         self.get_failed_message(), self.get_failed_destination_id(), self.get_error())),
23                     None,
24                     Author::parse("rnotify".to_owned()),
25                     self.get_failed_message().get_unix_timestamp_millis().clone(),
26        )
27    }
28}
29
30/// A struct containing information about what parts succeeded and what parts
31/// failed about [MessageRouter::route](crate::message_router::MessageRouter::route) attempt.
32#[derive(Debug)]
33pub struct SendErrors<'a> {
34    successfully_sent: usize,
35    original_message: &'a Message,
36    errors: Vec<ReportedSendError<'a>>,
37}
38
39impl<'a> SendErrors<'a> {
40
41    pub fn new(message: &'a Message, errors: Vec<ReportedSendError<'a>>, successfully_sent: usize) -> Self {
42        Self {
43            successfully_sent,
44            original_message: message,
45            errors,
46        }
47    }
48
49    /// Get the message that caused errors when sent.
50    pub fn get_message(&self) -> &Message {
51        self.original_message
52    }
53}
54
55impl<'a> Display for SendErrors<'a> {
56    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
57        writeln!(f, "-----")?;
58        writeln!(f, "Summary:")?;
59        writeln!(f, "Successfully sent to {} destinations", self.successfully_sent)?;
60        writeln!(f, "Failed to send to {} destinations", self.errors.len())?;
61        writeln!(f, "Message: {:?}", self.original_message)?;
62
63        for error in &self.errors {
64            writeln!(f, "--")?;
65            writeln!(f, "Failed to send a message to destination '{:?}'", error.get_failed_destination_id())?;
66            writeln!(f, "Due to error: {:?}", error.get_error())?;
67
68            let any_root_fails = error.get_report_summary().get_report_failures().is_empty();
69
70            if error.get_report_summary().was_reported() {
71                writeln!(f, "This was reported to atleast one destination.")?;
72            }
73            else if !any_root_fails {
74                // Not reported and no fails to report -> nowhere was applicable
75                writeln!(f, "No error receiving destinations were applicable to send this error to.")?;
76            }
77
78            if any_root_fails {
79                writeln!(f, "Some Error receiving destinations failed to be reported to.")?;
80
81                for err in error.get_report_summary().get_report_failures() {
82                    writeln!(f, "   - {:?}: {:?} ; Tried to send: {:?}", err.get_failed_destination_id(), err.get_error(), err.get_failed_message())?;
83                }
84            }
85        }
86        writeln!(f, "-----")
87    }
88}