• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

supabase / etl / 24713061833

21 Apr 2026 08:47AM UTC coverage: 78.316% (+0.07%) from 78.248%
24713061833

push

github

web-flow
refactor: enable extended clippy lint set (#675)

* refactor: explicit_iter_loop

* refactor: implicit_clone

* refactor: manual_let_else

* refactor: map_unwrap_or

* refactor: match_same_arms

* refactor: clippy::redundant_closure_for_method_calls

* refactor: redundant_clone

* refactor: redundant_test_prefix

* refactor: semicolon_if_nothing_returned

* refactor: uninlined_format_args

* refactor: unnested_or_patterns

* feat: enable extra lints

* fix: rebase

* fix: removed test

* fix: after rebase

* fix: fmt

* fix: http tests

* fix: rebase

* fix: fmt

* fix: fmt

414 of 503 new or added lines in 59 files covered. (82.31%)

3292 existing lines in 120 files now uncovered.

24379 of 31129 relevant lines covered (78.32%)

1069.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/etl-replicator/src/error.rs
1
use std::{backtrace::Backtrace, error::Error, fmt};
2

3
use etl::error::EtlError;
4

5
/// Returns whether terminal output should include backtraces.
UNCOV
6
fn should_render_backtrace() -> bool {
×
NEW
7
    matches!(std::env::var("RUST_BACKTRACE").as_deref(), Ok("1" | "full"))
×
8
}
×
9

10
/// Result type for replicator operations.
11
pub(crate) type ReplicatorResult<T> = Result<T, ReplicatorError>;
12

13
/// Captured backtrace wrapper to avoid thiserror's unstable feature detection.
14
pub(crate) struct CapturedBacktrace(Backtrace);
15

16
impl CapturedBacktrace {
17
    /// Captures a new backtrace for an error variant.
UNCOV
18
    fn capture() -> Self {
×
UNCOV
19
        Self(Backtrace::capture())
×
UNCOV
20
    }
×
21
}
22

23
impl fmt::Debug for CapturedBacktrace {
24
    /// Renders the wrapped backtrace for debugging output.
UNCOV
25
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
×
UNCOV
26
        write!(f, "{}", self.0)
×
UNCOV
27
    }
×
28
}
29

30
/// Error type for the replicator service.
31
///
32
/// Wraps [`EtlError`] for pipeline errors and provides variants for
33
/// infrastructure errors.
34
#[derive(Debug)]
35
pub(crate) enum ReplicatorError {
36
    /// Pipeline or ETL-related error.
37
    Etl(EtlError),
38
    /// Configuration error.
39
    Config(Box<dyn Error + Send + Sync>, CapturedBacktrace),
40
    /// Database migration error.
41
    Migration(sqlx::Error, CapturedBacktrace),
42
    /// I/O error.
43
    Io(std::io::Error, CapturedBacktrace),
44
}
45

46
impl ReplicatorError {
47
    /// Returns a short category label for this error.
UNCOV
48
    fn category(&self) -> &'static str {
×
UNCOV
49
        match self {
×
UNCOV
50
            ReplicatorError::Etl(_) => "replicator error",
×
UNCOV
51
            ReplicatorError::Config(_, _) => "configuration error",
×
52
            ReplicatorError::Migration(_, _) => "migration error",
×
53
            ReplicatorError::Io(_, _) => "i/o error",
×
54
        }
55
    }
×
56

57
    /// Returns the backtrace for this error.
UNCOV
58
    pub(crate) fn backtrace(&self) -> Option<&Backtrace> {
×
59
        match self {
×
UNCOV
60
            ReplicatorError::Etl(err) => err.backtrace(),
×
NEW
61
            ReplicatorError::Config(_, cb)
×
NEW
62
            | ReplicatorError::Migration(_, cb)
×
NEW
63
            | ReplicatorError::Io(_, cb) => Some(&cb.0),
×
64
        }
65
    }
×
66

67
    /// Creates a configuration error from any boxed source.
UNCOV
68
    pub(crate) fn config<E: Error + Send + Sync + 'static>(err: E) -> Self {
×
69
        ReplicatorError::Config(Box::new(err), CapturedBacktrace::capture())
×
UNCOV
70
    }
×
71

72
    /// Returns a user-oriented report for terminal output.
73
    pub(crate) fn render_report(&self) -> String {
×
74
        let mut out = String::new();
×
UNCOV
75
        out.push_str("replicator failed\n");
×
UNCOV
76
        out.push_str(&format!("category: {}\n", self.category()));
×
77
        out.push_str(&format!("error: {self}\n"));
×
78

79
        if !matches!(self, ReplicatorError::Etl(err) if err.errors().is_some()) {
×
80
            let mut source = Error::source(self);
×
81
            let mut idx = 1usize;
×
UNCOV
82
            while let Some(err) = source {
×
83
                out.push_str(&format!("cause {idx}: {err}\n"));
×
84
                source = err.source();
×
85
                idx += 1;
×
86
            }
×
87
        }
×
88

89
        if should_render_backtrace()
×
90
            && let Some(backtrace) = self.backtrace()
×
91
        {
UNCOV
92
            out.push_str("backtrace:\n");
×
93
            out.push_str(&backtrace.to_string());
×
94
            if !out.ends_with('\n') {
×
UNCOV
95
                out.push('\n');
×
96
            }
×
97
        }
×
98

99
        out
×
100
    }
×
101
}
102

103
impl fmt::Display for ReplicatorError {
104
    /// Renders a user-focused one-line description for terminal and log output.
UNCOV
105
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
×
UNCOV
106
        match self {
×
UNCOV
107
            ReplicatorError::Etl(err) => write!(f, "{err}"),
×
UNCOV
108
            ReplicatorError::Config(source, _) => write!(f, "configuration error: {source}"),
×
109
            ReplicatorError::Migration(source, _) => write!(f, "migration error: {source}"),
×
110
            ReplicatorError::Io(source, _) => write!(f, "i/o error: {source}"),
×
111
        }
112
    }
×
113
}
114

115
impl Error for ReplicatorError {
116
    /// Returns the direct cause for this error variant.
UNCOV
117
    fn source(&self) -> Option<&(dyn Error + 'static)> {
×
UNCOV
118
        match self {
×
UNCOV
119
            ReplicatorError::Etl(err) => err.source(),
×
UNCOV
120
            ReplicatorError::Config(source, _) => Some(source.as_ref()),
×
121
            ReplicatorError::Migration(source, _) => Some(source),
×
122
            ReplicatorError::Io(source, _) => Some(source),
×
123
        }
124
    }
×
125
}
126

127
impl From<sqlx::Error> for ReplicatorError {
128
    /// Converts a SQLx error into a migration error variant.
UNCOV
129
    fn from(err: sqlx::Error) -> Self {
×
UNCOV
130
        ReplicatorError::Migration(err, CapturedBacktrace::capture())
×
UNCOV
131
    }
×
132
}
133

134
impl From<std::io::Error> for ReplicatorError {
135
    /// Converts an I/O error into an I/O error variant.
UNCOV
136
    fn from(err: std::io::Error) -> Self {
×
UNCOV
137
        ReplicatorError::Io(err, CapturedBacktrace::capture())
×
UNCOV
138
    }
×
139
}
140

141
impl From<EtlError> for ReplicatorError {
142
    /// Converts an ETL error into a replicator ETL error variant.
UNCOV
143
    fn from(err: EtlError) -> Self {
×
UNCOV
144
        ReplicatorError::Etl(err)
×
UNCOV
145
    }
×
146
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc