Skip to main content

PostgresOutboxError

Enum PostgresOutboxError 

Source
#[non_exhaustive]
pub enum PostgresOutboxError { SchemaNotOnSearchPath { configured: String, observed: String, }, NotMigrated { schema: String, }, SchemaOutOfDate { schema: String, missing: &'static str, }, Database { source: Error, }, Decode { id: OutboxRecordId, message_id: MessageId, detail: String, }, UnknownMetadataVersion { id: OutboxRecordId, message_id: MessageId, version: i32, }, DuplicateMessage { id: MessageId, }, InvalidSchema { schema: String, }, UnsupportedServerVersion { required: u32, detected: u32, }, }
Expand description

A failure of a crate::PostgresOutboxStore OutboxStore/OutboxDeadLetters call — never a property of one row’s content. Row-content problems surface as reliar_outbox::PoisonedRows instead (ADR 0008).

Classify tells a dispatcher whether a failed call is worth retrying. The bare PostgresOutboxStore below leans on its default type parameter, gated on the default json feature; without it this block still shows the shape but is not compiled.

use reliar_core::Classify;
use reliar_outbox::{AcquireRequest, OutboxStore, WorkerId};

let request = AcquireRequest::new(WorkerId::generate());
if let Err(err) = store.acquire(request).await {
    eprintln!("acquire failed ({:?}): {err}", err.kind());
}

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

SchemaNotOnSearchPath

The unqualified name outbox does not resolve, or resolves to a different schema than configured. Carries the configured schema and the observed search_path; the ALTER ROLE remedy is in the Display text. Permanent.

Fields

§configured: String

The schema PostgresOutboxSettings::schema named.

§observed: String

The search_path Postgres reported at construction.

§

NotMigrated

outbox resolved to the configured schema, but the relation itself is missing — migrate() has not been run. Permanent. Mapped from SQLSTATE 42P01 on every path, not just startup verification.

Fields

§schema: String

The configured schema.

§

SchemaOutOfDate

outbox resolved to the configured schema and the relation exists, but it has not finished a required migration — missing names the first column that is either absent or present but still nullable (a completion marker, not a bare inventory check: id exists from migration 0005 onward but stays nullable until 0010’s SET NOT NULL, so a schema stuck anywhere in 00050009 is reported the same as one stuck at 0004). Checked at crate::PostgresOutboxStore::connect, after the search_path verification above and only once the relation is confirmed to exist there: a wrong search_path or a missing relation each already has its own variant, so this one means specifically “the right table, an old shape” (ADR 0044 Amendment A.4, marker corrected by Amendment A.5) — today, message_id or id (migrations 00050010). The remedy is migrate(&pool, ..), never a search_path fix. Permanent — the column will not satisfy itself.

Fields

§schema: String

The configured schema.

§missing: &'static str

The first required column this build did not find satisfied (absent, or present but still nullable) on the resolved relation.

§

Database

Connection lost, statement timeout, pool exhausted, deadlock, or any other sqlx failure not mapped to a more specific variant above. Classified by the wrapped SQLSTATE’s class (never blanket-transient — see the Classify impl below).

Fields

§source: Error

The underlying sqlx error.

§

Decode

A claimed or listed row could not be turned into an OutboxRecord (a corrupt JSONB remainder, an unparseable promoted column). Surfaces as a poisoned row, never as an acquire/list_dead failure. Permanent — the bytes on disk do not change between attempts. Carries both ids (ADR 0044 A.2) — id and message_id are plain uuid columns and are always readable even when the envelope columns that failed to decode are not.

Fields

§id: OutboxRecordId

The row’s own identity.

§message_id: MessageId

The row’s message id.

§detail: String

A short, payload-free description of what failed to decode.

§

UnknownMetadataVersion

The row’s metadata_version is not one this build knows how to read. Permanent — it needs a newer reader, not another try. Carries both ids, see Self::Decode.

Fields

§id: OutboxRecordId

The row’s own identity.

§message_id: MessageId

The row’s message id.

§version: i32

The unrecognised version.

§

DuplicateMessage

enqueue inserted a MessageId that already exists (ix_outbox_message_id violation, ADR 0044 §1). Permanent — a reused id never succeeds on retry; the row is already there. Unlike Self::Decode/Self::UnknownMetadataVersion this carries only the message id: the caller already knows it, and the row it collided with is not this call’s concern (ADR 0044 A.2 — a pk_outbox collision, a record-id repeat, is a different, non-caller error and stays Database).

Fields

§id: MessageId

The id the caller tried to reuse.

§

InvalidSchema

PostgresOutboxSettings::schema or MigrateOptions::schema is not a valid PostgreSQL identifier ([a-z_][a-z0-9_$]*, at most 63 bytes, lowercase only) — checked once, before it is ever interpolated into SET search_path/dangerous_set_table_name. Lowercase-only rather than merely case-insensitive: PostgreSQL folds an unquoted identifier to lowercase, so an uppercase configured name and the schema it actually resolves to would silently disagree unless every one of migrate()’s, this crate’s own schema check’s and the host’s own search_path configuration happened to quote it the same way everywhere — rejecting it up front removes the whole class of mismatch. Permanent — configuration, not weather.

Fields

§schema: String

The rejected schema name.

§

UnsupportedServerVersion

The connected server’s server_version_num is below crate::MIN_SERVER_VERSION_NUM (PostgreSQL 18, ADR 0041) — no older-version fallback. Checked at crate::PostgresOutboxStore::connect, before the search_path verification above: a wrong server version explains a missing relation, and the reverse is never true. Carries no connection string, host, or credentials. Permanent.

Fields

§required: u32

crate::MIN_SERVER_VERSION_NUM, restated on the value so this variant is self-describing without a second lookup.

§detected: u32

The server_version_num this connection reported.

Trait Implementations§

Source§

impl Classify for PostgresOutboxError

Per-variant classification table — no blanket “everything else is transient”. A wrong verdict is not cosmetic: Transient burns the dispatcher’s retry budget on a failure that can never succeed; Permanent kills a message that would have gone through on the next attempt.

Source§

fn kind(&self) -> FailureKind

Whether the failure this error represents can succeed on retry. Read more
Source§

impl Debug for PostgresOutboxError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for PostgresOutboxError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for PostgresOutboxError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0:

use the Display impl or to_string()

1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0:

replaced by Error::source, which can support downcasting

Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<Error> for PostgresOutboxError

Source§

fn from(source: Error) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more