strut_rabbitmq/transport/outbound/publisher/
api.rs1use crate::transport::outbound::publisher::inner::{
2 NotConfirmed, NotTransmitted, PartlyConfirmedBatch,
3};
4use crate::Dispatch;
5use nonempty::NonEmpty;
6use std::fmt::{Display, Formatter};
7use thiserror::Error;
8
9pub type PublishingResult = Result<Dispatch, PublishingError>;
11
12pub type BatchPublishingResult = Result<Vec<Dispatch>, BatchPublishingError>;
14
15#[derive(Error, Debug)]
17#[error("failed to publish a RabbitMQ message: {failure}")]
18pub struct PublishingError {
19 pub dispatch: Dispatch,
21 pub failure: PublishingFailure,
23}
24
25#[derive(Error, Debug)]
27#[error(
28 "failed to fully publish a batch of {} RabbitMQ messages: {} messages went through, {} messages did not go through",
29 published.len() + not_published.len(),
30 published.len(),
31 not_published.len(),
32)]
33pub struct BatchPublishingError {
34 pub published: Vec<Dispatch>,
36 pub not_published: NonEmpty<PublishingError>,
38}
39
40#[derive(Debug)]
42pub enum PublishingFailure {
43 NotTransmitted,
45 NegativelyAcknowledged,
48 BrokerError,
51 CommunicationError,
53}
54
55impl Display for PublishingFailure {
56 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
57 match self {
58 PublishingFailure::NotTransmitted => {
59 f.write_str("the message was not transmitted to the broker")
60 }
61 PublishingFailure::NegativelyAcknowledged => f.write_str(concat!(
62 "the message was negatively acknowledged by the broker",
63 " (not routed to an exchange or a queue, depending on",
64 " confirmation level)",
65 )),
66 PublishingFailure::BrokerError => f.write_str(
67 "the broker suffered an internal error during acknowledgement of the message",
68 ),
69 PublishingFailure::CommunicationError => {
70 f.write_str("failed to retrieve the acknowledgement from the broker")
71 }
72 }
73 }
74}
75
76impl From<NotTransmitted> for PublishingError {
77 fn from(value: NotTransmitted) -> Self {
78 let dispatch = match value {
79 NotTransmitted::NotAttempted(dispatch) => dispatch,
80 NotTransmitted::TransmissionError(dispatch, _) => dispatch,
81 };
82
83 Self {
84 dispatch,
85 failure: PublishingFailure::NotTransmitted,
86 }
87 }
88}
89
90impl From<NotConfirmed> for PublishingError {
91 fn from(value: NotConfirmed) -> Self {
92 match value {
93 NotConfirmed::NotAttempted(dispatch) => Self {
94 dispatch,
95 failure: PublishingFailure::NotTransmitted,
96 },
97 NotConfirmed::TransmissionError(dispatch, _error) => Self {
98 dispatch,
99 failure: PublishingFailure::NotTransmitted,
100 },
101 NotConfirmed::Negative(dispatch, _return) => Self {
102 dispatch,
103 failure: PublishingFailure::NegativelyAcknowledged,
104 },
105 NotConfirmed::BrokerError(dispatch, _return) => Self {
106 dispatch,
107 failure: PublishingFailure::BrokerError,
108 },
109 NotConfirmed::ConfirmationError(dispatch, _error) => Self {
110 dispatch,
111 failure: PublishingFailure::CommunicationError,
112 },
113 }
114 }
115}
116
117impl From<PartlyConfirmedBatch> for BatchPublishingError {
118 fn from(value: PartlyConfirmedBatch) -> Self {
119 BatchPublishingError {
120 published: value
121 .confirmed_dispatches
122 .into_iter()
123 .map(Dispatch::from)
124 .collect(),
125 not_published: value.not_confirmed_dispatches.map(PublishingError::from),
126 }
127 }
128}