runledger_runtime/
error.rs1use thiserror::Error;
2
3pub type Result<T> = std::result::Result<T, Error>;
4
5#[derive(Debug, Error)]
6pub enum Error {
7 #[error(transparent)]
8 Scheduler(#[from] SchedulerError),
9 #[error(transparent)]
10 Worker(#[from] WorkerError),
11 #[error(transparent)]
12 Reaper(#[from] ReaperError),
13 #[error(transparent)]
14 Runtime(#[from] RuntimeError),
15}
16
17#[derive(Debug, Error)]
18pub enum SchedulerError {
19 #[error("failed to begin scheduler transaction")]
20 BeginTransaction { source: runledger_postgres::Error },
21 #[error("failed to commit scheduler transaction")]
22 CommitTransaction { source: runledger_postgres::Error },
23 #[error("failed to claim due schedules")]
24 ClaimDueSchedules { source: runledger_postgres::Error },
25 #[error("failed to create savepoint using `{statement}`")]
26 SavepointCreate {
27 statement: &'static str,
28 source: runledger_postgres::Error,
29 },
30 #[error("failed to rollback savepoint using `{statement}`")]
31 SavepointRollback {
32 statement: &'static str,
33 source: runledger_postgres::Error,
34 },
35 #[error("failed to release savepoint using `{statement}`")]
36 SavepointRelease {
37 statement: &'static str,
38 source: runledger_postgres::Error,
39 },
40 #[error("failed deferring failed schedule `{schedule_id}`")]
41 DeferFailedSchedule {
42 schedule_id: uuid::Uuid,
43 source: runledger_postgres::Error,
44 },
45 #[error(
46 "invalid cron expression for schedule `{schedule_name}` ({schedule_id}): `{cron_expr}`"
47 )]
48 InvalidCronExpression {
49 schedule_id: uuid::Uuid,
50 schedule_name: String,
51 cron_expr: String,
52 },
53 #[error("failed enqueueing scheduled job `{job_type}` from schedule `{schedule_id}`")]
54 EnqueueScheduledJob {
55 schedule_id: uuid::Uuid,
56 job_type: String,
57 source: runledger_postgres::Error,
58 },
59 #[error("failed marking schedule `{schedule_id}` as fired")]
60 MarkScheduleFired {
61 schedule_id: uuid::Uuid,
62 source: runledger_postgres::Error,
63 },
64}
65
66#[derive(Debug, Error)]
67pub enum WorkerError {
68 #[error("failed claiming jobs for worker `{worker_id}`")]
69 ClaimJobs {
70 worker_id: String,
71 source: runledger_postgres::Error,
72 },
73 #[error("failed setting running progress for job `{job_id}` attempt `{attempt}`")]
74 SetRunningProgress {
75 job_id: uuid::Uuid,
76 attempt: i32,
77 source: runledger_postgres::Error,
78 },
79 #[error("failed releasing unstarted claim for job `{job_id}` attempt `{attempt}`")]
80 ReleaseUnstartedClaim {
81 job_id: uuid::Uuid,
82 attempt: i32,
83 source: runledger_postgres::Error,
84 },
85 #[error("failed completing job `{job_id}` attempt `{attempt}` as success")]
86 CompleteSuccess {
87 job_id: uuid::Uuid,
88 attempt: i32,
89 source: runledger_postgres::Error,
90 },
91 #[error("failed completing job `{job_id}` attempt `{attempt}` as failure")]
92 CompleteFailure {
93 job_id: uuid::Uuid,
94 attempt: i32,
95 source: runledger_postgres::Error,
96 },
97 #[error("failed heartbeat for job `{job_id}` attempt `{attempt}`")]
98 Heartbeat {
99 job_id: uuid::Uuid,
100 attempt: i32,
101 source: runledger_postgres::Error,
102 },
103}
104
105#[derive(Debug, Error)]
106pub enum ReaperError {
107 #[error(
108 "failed reaping expired leases with batch_size `{batch_size}` and retry_delay_ms `{retry_delay_ms}`"
109 )]
110 ReapExpiredLeases {
111 batch_size: i64,
112 retry_delay_ms: i32,
113 source: runledger_postgres::Error,
114 },
115}
116
117#[derive(Debug, Error)]
118pub enum RuntimeError {
119 #[error("jobs runtime task `{task}` exited unexpectedly before shutdown")]
120 TaskExitedUnexpectedly { task: &'static str },
121 #[error("failed joining jobs runtime task `{task}`")]
122 TaskJoin {
123 task: &'static str,
124 #[source]
125 source: tokio::task::JoinError,
126 },
127}
128
129#[cfg(test)]
130mod tests {
131 use super::*;
132
133 #[test]
134 fn scheduler_invalid_cron_variant_contains_schedule_metadata() {
135 let schedule_id = uuid::Uuid::nil();
136 let error = SchedulerError::InvalidCronExpression {
137 schedule_id,
138 schedule_name: "nightly sync".to_string(),
139 cron_expr: "not cron".to_string(),
140 };
141
142 match error {
143 SchedulerError::InvalidCronExpression {
144 schedule_id: actual_id,
145 schedule_name,
146 cron_expr,
147 } => {
148 assert_eq!(actual_id, schedule_id);
149 assert_eq!(schedule_name, "nightly sync");
150 assert_eq!(cron_expr, "not cron");
151 }
152 other => panic!("expected invalid cron variant, got: {other:?}"),
153 }
154 }
155}