Skip to main content

systemprompt_events/
error.rs

1//! Error types raised by the event-broadcasting infrastructure.
2//!
3//! [`EventError`] is the public, `thiserror`-derived enum returned from every
4//! fallible operation in the crate. It composes via `#[from]` with
5//! `serde_json::Error` so callers can compose it into larger error enums
6//! without wrapping by hand.
7//!
8//! Copyright (c) systemprompt.io — Business Source License 1.1.
9//! See <https://systemprompt.io> for licensing details.
10
11use thiserror::Error;
12
13#[derive(Debug, Error)]
14pub enum EventError {
15    #[error("event serialization failed: {0}")]
16    Serialization(#[from] serde_json::Error),
17
18    #[error("event channel saturated for {target}")]
19    ChannelFull { target: String },
20}
21
22pub type EventResult<T> = Result<T, EventError>;
23
24/// Why a routed event did not reach the cross-replica outbox.
25#[derive(Debug, Error)]
26pub enum RelayError {
27    #[error("event serialization failed for outbox channel {channel}: {source}")]
28    Serialize {
29        channel: &'static str,
30        #[source]
31        source: serde_json::Error,
32    },
33    #[error("failed to persist outbox row on channel {channel}: {source}")]
34    Persist {
35        channel: &'static str,
36        #[source]
37        source: sqlx::Error,
38    },
39    #[error("outbox row persisted but NOTIFY failed: {0}")]
40    Notify(#[source] sqlx::Error),
41}
42
43/// Whether a routed event was handed to the other replicas.
44#[derive(Debug)]
45pub enum RelayOutcome {
46    NotInstalled,
47    Relayed,
48    Failed(RelayError),
49}
50
51/// Local fan-out counts plus the cross-replica relay result of one `route_*`.
52#[derive(Debug)]
53#[must_use = "a failed relay is only visible through this outcome"]
54pub struct RouteOutcome<L> {
55    pub local: L,
56    pub relay: RelayOutcome,
57}
58
59impl<L> RouteOutcome<L> {
60    pub fn into_local_logged(self) -> L {
61        if let RelayOutcome::Failed(error) = &self.relay {
62            tracing::warn!(error = %error, "event routed locally but not relayed to other replicas");
63        }
64        self.local
65    }
66}