diff options
Diffstat (limited to 'internal/app/errors.go')
| -rw-r--r-- | internal/app/errors.go | 184 |
1 files changed, 0 insertions, 184 deletions
diff --git a/internal/app/errors.go b/internal/app/errors.go deleted file mode 100644 index f7fa2b1c..00000000 --- a/internal/app/errors.go +++ /dev/null @@ -1,184 +0,0 @@ -package app - -import ( - "errors" - "log" - - "hakurei.app/container" - "hakurei.app/hst" - "hakurei.app/internal/hlog" - "hakurei.app/internal/sys" -) - -// PrintRunStateErr prints an error message via [log] if runErr is not nil, and returns an appropriate exit code. -// -// TODO(ophestra): remove this function once RunState has been replaced -func PrintRunStateErr(rs *RunState, runErr error) (code int) { - code = rs.ExitStatus() - - if runErr != nil { - if rs.Time == nil { - // no process has been created - printMessageError("cannot start app:", runErr) - } else { - if m, ok := container.GetErrorMessage(runErr); !ok { - // catch-all for unexpected errors - log.Println("run returned error:", runErr) - } else { - var se *StateStoreError - if !errors.As(runErr, &se) { - // this could only be returned from a shim setup failure path - log.Print(m) - } else { - // InnerErr is returned by c.Save(&sd, seal.ct), and are always unwrapped - printMessageError("error returned during revert:", - &hst.AppError{Step: "save process state", Err: se.InnerErr}) - } - } - } - - if code == 0 { - code = 126 - } - } - - if rs.RevertErr != nil { - var stateStoreError *StateStoreError - if !errors.As(rs.RevertErr, &stateStoreError) || stateStoreError == nil { - printMessageError("cannot clean up:", rs.RevertErr) - goto out - } - - if stateStoreError.Errs != nil { - if len(stateStoreError.Errs) == 2 { // storeErr.save(revertErr, store.Close()) - if stateStoreError.Errs[0] != nil { // revertErr is MessageError joined by errors.Join - var joinedErrors interface { - Unwrap() []error - error - } - if !errors.As(stateStoreError.Errs[0], &joinedErrors) { - printMessageError("cannot revert:", stateStoreError.Errs[0]) - } else { - for _, err := range joinedErrors.Unwrap() { - if err != nil { - printMessageError("cannot revert:", err) - } - } - } - } - if stateStoreError.Errs[1] != nil { // store.Close() is joined by errors.Join - log.Printf("cannot close store: %v", stateStoreError.Errs[1]) - } - } else { - log.Printf("fault during cleanup: %v", errors.Join(stateStoreError.Errs...)) - } - } - - if stateStoreError.OpErr != nil { - log.Printf("blind revert due to store fault: %v", stateStoreError.OpErr) - } - - if stateStoreError.DoErr != nil { - printMessageError("state store operation unsuccessful:", stateStoreError.DoErr) - } - - if stateStoreError.Inner && stateStoreError.InnerErr != nil { - printMessageError("cannot destroy state entry:", stateStoreError.InnerErr) - } - - out: - if code == 0 { - code = 128 - } - } - if rs.WaitErr != nil { - hlog.Verbosef("wait: %v", rs.WaitErr) - } - return -} - -// TODO(ophestra): this duplicates code in cmd/hakurei/command.go, keep this up to date until removal -func printMessageError(fallback string, err error) { - // this indicates the error message has already reached stderr, outside the current process's control; - // this is only reached when hsu fails for any reason, as a second error message following hsu is confusing - if errors.Is(err, sys.ErrHsuAccess) { - hlog.Verbose("*"+fallback, err) - return - } - - m, ok := container.GetErrorMessage(err) - if !ok { - log.Println(fallback, err) - return - } - - log.Print(m) -} - -// StateStoreError is returned for a failed state save. -type StateStoreError struct { - // whether inner function was called - Inner bool - // returned by the Save/Destroy method of [state.Cursor] - InnerErr error - // returned by the Do method of [state.Store] - DoErr error - // stores an arbitrary store operation error - OpErr error - // stores arbitrary errors - Errs []error -} - -// save saves arbitrary errors in [StateStoreError.Errs] once. -func (e *StateStoreError) save(errs ...error) { - if len(errs) == 0 || e.Errs != nil { - panic("invalid call to save") - } - e.Errs = errs -} - -// equiv returns an error that [StateStoreError] is equivalent to, including nil. -func (e *StateStoreError) equiv(step string) error { - if e.Inner && e.InnerErr == nil && e.DoErr == nil && e.OpErr == nil && errors.Join(e.Errs...) == nil { - return nil - } else { - return &hst.AppError{Step: step, Err: e} - } -} - -func (e *StateStoreError) Error() string { - if e.Inner && e.InnerErr != nil { - return e.InnerErr.Error() - } - if e.DoErr != nil { - return e.DoErr.Error() - } - if e.OpErr != nil { - return e.OpErr.Error() - } - if err := errors.Join(e.Errs...); err != nil { - return err.Error() - } - - // equiv nullifies e for values where this is reached - panic("unreachable") -} - -func (e *StateStoreError) Unwrap() (errs []error) { - errs = make([]error, 0, 3+len(e.Errs)) - if e.InnerErr != nil { - errs = append(errs, e.InnerErr) - } - if e.DoErr != nil { - errs = append(errs, e.DoErr) - } - if e.OpErr != nil { - errs = append(errs, e.OpErr) - } - for _, err := range e.Errs { - if err != nil { - errs = append(errs, err) - } - } - return -} |
