aboutsummaryrefslogtreecommitdiffhomepage
path: root/system/output.go
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-08-30 22:49:12 +0900
committerOphestra <cat@gensokyo.uk>2025-08-30 22:49:12 +0900
commitf5abce9df5727904a1daa246025a87c4bfe62553 (patch)
tree7e8c29b83e97532954dee8adb5f86962eaebca34 /system/output.go
parentddb003e39b64c2417cabc291383d99b4ad64ac8f (diff)
system: wrap op errors
This passes more information allowing for better error handling. This eliminates generic WrapErr from system. Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'system/output.go')
-rw-r--r--system/output.go58
1 files changed, 56 insertions, 2 deletions
diff --git a/system/output.go b/system/output.go
index 303f7493..ec1802b6 100644
--- a/system/output.go
+++ b/system/output.go
@@ -1,6 +1,10 @@
package system
import (
+ "errors"
+ "net"
+ "os"
+
"hakurei.app/container"
)
@@ -14,9 +18,59 @@ func SetOutput(v container.Msg) {
}
}
-func wrapErrSuffix(err error, a ...any) error {
+// OpError is returned by [I.Commit] and [I.Revert].
+type OpError struct {
+ Op string
+ Err error
+ Message string
+ Revert bool
+}
+
+func (e *OpError) Unwrap() error { return e.Err }
+func (e *OpError) Error() string {
+ if e.Message != "" {
+ return e.Message
+ }
+
+ switch {
+ case errors.As(e.Err, new(*os.PathError)), errors.As(e.Err, new(*net.OpError)):
+ return e.Err.Error()
+
+ default:
+ if !e.Revert {
+ return "cannot apply " + e.Op + ": " + e.Err.Error()
+ } else {
+ return "cannot revert " + e.Op + ": " + e.Err.Error()
+ }
+ }
+}
+
+// newOpError returns an [OpError] without a message string.
+func newOpError(op string, err error, revert bool) error {
if err == nil {
return nil
}
- return msg.WrapErr(err, append(a, err)...)
+ return &OpError{op, err, "", revert}
+}
+
+// newOpErrorMessage returns an [OpError] with an overriding message string.
+func newOpErrorMessage(op string, err error, message string, revert bool) error {
+ if err == nil {
+ return nil
+ }
+ return &OpError{op, err, message, revert}
+}
+
+func printJoinedError(println func(v ...any), fallback string, err error) {
+ var joinErr interface {
+ Unwrap() []error
+ error
+ }
+ if !errors.As(err, &joinErr) {
+ println(fallback, err)
+ } else {
+ for _, err = range joinErr.Unwrap() {
+ println(err.Error())
+ }
+ }
}