From 985fea6639346385ec3be86e8a4af70296ad316f Mon Sep 17 00:00:00 2001 From: dev_agent Date: Sat, 3 Oct 2026 15:16:18 -0400 Subject: [PATCH] Store "interrupted by restart" for jobs recovered at boot Boot recovery now writes the required fixed text to the job error column, and the recovery test asserts that literal text instead of the constant. Co-Authored-By: Claude Opus 5.5 --- internal/jobs/jobs.go | 6 ++++-- internal/jobs/jobs_test.go | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/internal/jobs/jobs.go b/internal/jobs/jobs.go index 16f3b5f..583d75d 100644 --- a/internal/jobs/jobs.go +++ b/internal/jobs/jobs.go @@ -41,7 +41,9 @@ const ( // Failure codes the runner stores itself. A kind cannot declare them. const ( // CodeInterrupted is the error of a job a previous process left running. - CodeInterrupted = "interrupted" + // It is fixed framework text, not a snake-case code, so no kind can + // declare it. + CodeInterrupted = "interrupted by restart" // CodeInternal is the error of a job whose handler failed with anything // but a *Failure with a code its kind declared, or whose payload or // result could not be encoded. The underlying error is neither stored @@ -152,7 +154,7 @@ func Register[P any, R Public](r *Runner, kind string, h Handler[P, R], failureC if !codePattern.MatchString(code) { return nil, fmt.Errorf("jobs: register %q: failure code %q is not lower-case snake case", kind, code) } - if code == CodeInterrupted || code == CodeInternal || code == CodeUnknownKind { + if code == CodeInternal || code == CodeUnknownKind { return nil, fmt.Errorf("jobs: register %q: failure code %q is reserved for the runner", kind, code) } declared[code] = true diff --git a/internal/jobs/jobs_test.go b/internal/jobs/jobs_test.go index 6ea3239..7a3395d 100644 --- a/internal/jobs/jobs_test.go +++ b/internal/jobs/jobs_test.go @@ -391,8 +391,8 @@ func TestRestartFailsInterruptedJobsAndRunsQueuedOnes(t *testing.T) { start(t, second) job := waitFor(t, second, interrupted, finished) - if job.Status != StatusFailed || job.Error == nil || *job.Error != CodeInterrupted { - t.Errorf("interrupted job = %+v, want failed with %q", job, CodeInterrupted) + if job.Status != StatusFailed || job.Error == nil || *job.Error != "interrupted by restart" { + t.Errorf("interrupted job = %+v, want failed with %q", job, "interrupted by restart") } if string(job.Result) != `{"done":1}` { t.Errorf("interrupted job result = %s, want the last partial result kept", job.Result)