reminders: persist + surface delivery failures
Broker schema gains attempt_count INTEGER + last_error TEXT
columns via idempotent ALTER TABLE migration (pragma-probed so
fresh + existing dbs converge). reminder_scheduler::tick calls
record_reminder_failure on every deliver_reminder error,
bumping the counter + stashing the message. get_due_reminders
filters out rows where attempt_count >= MAX_REMINDER_ATTEMPTS
(5) so the scheduler stops retrying a stuck row until the
operator intervenes.
new POST /retry-reminder/{id} → reset_reminder_failure clears
the counters; next 5s tick re-attempts. cancel-reminder
unchanged (hard-delete).
dashboard renders failed rows with a red left rule, the error
text inline, and a ⚠ N failed badge. ↻ R3TRY button appears
when attempt_count > 0 — sits next to ✗ C4NC3L in a small
actions row below the body.
This commit is contained in:
parent
d395bdc945
commit
978a3cf391
5 changed files with 173 additions and 8 deletions
|
|
@ -71,12 +71,24 @@ fn tick(coord: &Arc<Coordinator>) {
|
|||
for (agent, id, message, file_path) in due {
|
||||
let body = prepare_body(&agent, &message, file_path.as_deref());
|
||||
if let Err(e) = coord.broker.deliver_reminder(id, &agent, &body) {
|
||||
let reason = format!("{e:#}");
|
||||
tracing::warn!(
|
||||
reminder_id = id,
|
||||
%agent,
|
||||
error = ?e,
|
||||
error = %reason,
|
||||
"failed to deliver reminder"
|
||||
);
|
||||
// Persist the failure so the dashboard can surface it +
|
||||
// bump attempt_count. After MAX_REMINDER_ATTEMPTS the
|
||||
// row drops out of `get_due_reminders` and waits for
|
||||
// operator retry / cancel.
|
||||
if let Err(persist_err) = coord.broker.record_reminder_failure(id, &reason) {
|
||||
tracing::warn!(
|
||||
reminder_id = id,
|
||||
error = ?persist_err,
|
||||
"failed to persist reminder failure"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue