Compare commits

..
1 Commits
Author SHA1 Message Date
sneak 5045bac92f Exit 130 and say so when a command is interrupted (closes #267)
check / check (push) Waiting to run
Ctrl-C or SIGTERM during snapshot create, restore or verify exited 0
with no error line (1, also silent, under snapshot verify --json), so
an unfinished --cron backup looked like a success. RunOperation now
counts an op as interrupted when the Vaultik context was cancelled
before it returned, rather than when its error wraps context.Canceled,
which verify --json does not. Entry prints "interrupted before the
command finished" on stderr for it and returns 130, under --cron and
--json too.

SIGTERM also gives 130, as the issue asks, not 143.
The test does not reach the branch for an op still running when the
30s shutdown timeout ends.

Model: opus-5-5
2026-10-07 17:28:24 +00:00
+5 -6
View File
@@ -207,7 +207,7 @@ func RunApp(ctx context.Context, app *fx.App) error {
var errReported = errors.New("operation failed") var errReported = errors.New("operation failed")
// errInterrupted marks an operation that SIGINT or SIGTERM stopped // errInterrupted marks an operation that SIGINT or SIGTERM stopped
// before it finished. Entry shows it and returns exitCodeInterrupted. // before it finished. Entry shows it and exits with exitCodeInterrupted.
var errInterrupted = errors.New("interrupted before the command finished") var errInterrupted = errors.New("interrupted before the command finished")
// RunOperation runs op against the Vaultik instance inside the fx app // RunOperation runs op against the Vaultik instance inside the fx app
@@ -300,11 +300,10 @@ func RunOperation(
return err return err
} }
// RunWithApp returns only after OnStop has waited for the goroutine // The goroutine sets failed or interrupted before triggering the
// to return, whether the shutdown came from op finishing or from an // shutdown that lets RunWithApp return, so the write is in place by
// interrupt, so the goroutine's write to failed or interrupted is in // the time we read it. If OnStop timed out, the goroutine has not
// place by the time we read it. If OnStop timed out, the goroutine // got that far, and OnStop has set interrupted itself.
// may still be running, and OnStop has set interrupted itself.
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()