app: handle RunState errors
All checks were successful
Test / Create distribution (push) Successful in 25s
Test / Fortify (push) Successful in 2m27s
Test / Data race detector (push) Successful in 3m24s
Test / Fpkg (push) Successful in 3m30s
Test / Flake checks (push) Successful in 52s

Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
2025-02-26 17:36:14 +09:00
parent 741d011543
commit 840ceb615a
3 changed files with 105 additions and 108 deletions

67
main.go
View File

@@ -286,74 +286,17 @@ func buildCommand(out io.Writer) command.Command {
}
func runApp(a fst.App, config *fst.Config) {
rs := new(fst.RunState)
ctx, stop := signal.NotifyContext(context.Background(),
syscall.SIGINT, syscall.SIGTERM)
defer stop() // unreachable
rs := new(fst.RunState)
if sa, err := a.Seal(config); err != nil {
fmsg.PrintBaseError(err, "cannot seal app:")
internal.Exit(1)
} else if err = sa.Run(ctx, rs); err != nil {
if rs.Time == nil {
fmsg.PrintBaseError(err, "cannot start app:")
} else {
logWaitError(err)
}
if rs.ExitCode == 0 {
rs.ExitCode = 126
}
}
if rs.RevertErr != nil {
var stateStoreError *app.StateStoreError
if !errors.As(rs.RevertErr, &stateStoreError) || stateStoreError == nil {
fmsg.PrintBaseError(rs.RevertErr, "generic fault during cleanup:")
goto out
}
if stateStoreError.Err != nil {
if len(stateStoreError.Err) == 2 {
if stateStoreError.Err[0] != nil {
if joinedErrs, ok := stateStoreError.Err[0].(interface{ Unwrap() []error }); !ok {
fmsg.PrintBaseError(stateStoreError.Err[0], "generic fault during revert:")
} else {
for _, err := range joinedErrs.Unwrap() {
if err != nil {
fmsg.PrintBaseError(err, "fault during revert:")
}
}
}
}
if stateStoreError.Err[1] != nil {
log.Printf("cannot close store: %v", stateStoreError.Err[1])
}
} else {
log.Printf("fault during cleanup: %v",
errors.Join(stateStoreError.Err...))
}
}
if stateStoreError.OpErr != nil {
log.Printf("blind revert due to store fault: %v",
stateStoreError.OpErr)
}
if stateStoreError.DoErr != nil {
fmsg.PrintBaseError(stateStoreError.DoErr, "state store operation unsuccessful:")
}
if stateStoreError.Inner && stateStoreError.InnerErr != nil {
fmsg.PrintBaseError(stateStoreError.InnerErr, "cannot destroy state entry:")
}
out:
if rs.ExitCode == 0 {
rs.ExitCode = 128
}
}
if rs.WaitErr != nil {
log.Println("inner wait failed:", rs.WaitErr)
rs.ExitCode = 1
} else {
// this updates ExitCode
app.PrintRunStateErr(rs, sa.Run(ctx, rs))
}
internal.Exit(rs.ExitCode)
}