1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
//! `sqlx::Error` → [`EngineError`] mapping for the Postgres backend.
//!
//! **RFC-v0.7 Wave 0.** This is a map-sketch: enough surface for
//! subsequent waves' trait-method bodies to route transport faults
//! through `EngineError::Transport { backend: "postgres", .. }` plus
//! the two typed cases the design-question matrix already pinned:
//!
//! * `SqlState::UniqueViolation` (`23505`) → [`EngineError::Conflict`]
//! — mirrors the Valkey backend's conflict classification for
//! duplicate-key writes (e.g. waitpoint id collision, unique
//! index violation on `ff_completion_event` etc.).
//! * `SqlState::SerializationFailure` (`40001`) / `DeadlockDetected`
//! (`40P01`) → [`EngineError::Contention`] — per Q11 (isolation
//! level default) these are the retryable serialization faults
//! SERIALIZABLE can raise; callers retry per RFC-010 §10.7.
//!
//! Every other `sqlx::Error` boxes through `Transport` as a safe
//! default. Future waves refine (e.g. `RowNotFound` → `NotFound`,
//! connection-pool-closed → `Unavailable`).
use ;
/// Convert a `sqlx::Error` into an [`EngineError`].
///
/// Kept as a free function (rather than a `From` impl) so call sites
/// can thread extra context (method label, key, etc.) through
/// [`ff_core::engine_error::backend_context`] alongside. A blanket
/// `From<sqlx::Error> for EngineError` is also provided below for
/// ergonomics in `?` chains where no extra context is needed.
/// Thin newtype over `sqlx::Error` so a blanket
/// `From<sqlx::Error> for EngineError` doesn't conflict with
/// ff-core's own orphan rules when downstream crates add their own.
/// Backend-internal call sites use [`map_sqlx_error`] directly; this
/// wrapper exists for future cases where we want to attach a
/// typed source to a different `EngineError` variant.
;