aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra Umiker <cat@ophivana.moe>2024-10-16 01:29:44 +0900
committerOphestra Umiker <cat@ophivana.moe>2024-10-16 01:29:44 +0900
commit0fd63e85e730d44abd488c892be377b332f5458e (patch)
tree715045b4395ab3206071b845039581f2c4a2a14d
parent33cf0bed540a9b2c439bdca4869af8faf9f52cf4 (diff)
fmsg/errors: isolate app/error into a separate package
These functions are not in any way specific to the app package. Signed-off-by: Ophestra Umiker <cat@ophivana.moe>
-rw-r--r--internal/fmsg/errors.go72
-rw-r--r--internal/fmsg/fmsg.go2
2 files changed, 74 insertions, 0 deletions
diff --git a/internal/fmsg/errors.go b/internal/fmsg/errors.go
new file mode 100644
index 00000000..079c5556
--- /dev/null
+++ b/internal/fmsg/errors.go
@@ -0,0 +1,72 @@
+package fmsg
+
+import (
+ "fmt"
+ "reflect"
+)
+
+// baseError implements a basic error container
+type baseError struct {
+ Err error
+}
+
+func (e *baseError) Error() string {
+ return e.Err.Error()
+}
+
+func (e *baseError) Unwrap() error {
+ return e.Err
+}
+
+// BaseError implements an error container with a user-facing message
+type BaseError struct {
+ message string
+ baseError
+}
+
+// Message returns a user-facing error message
+func (e *BaseError) Message() string {
+ return e.message
+}
+
+// WrapError wraps an error with a corresponding message.
+func WrapError(err error, a ...any) error {
+ if err == nil {
+ return nil
+ }
+ return wrapError(err, fmt.Sprintln(a...))
+}
+
+// WrapErrorSuffix wraps an error with a corresponding message with err at the end of the message.
+func WrapErrorSuffix(err error, a ...any) error {
+ if err == nil {
+ return nil
+ }
+ return wrapError(err, fmt.Sprintln(append(a, err)...))
+}
+
+// WrapErrorFunc wraps an error with a corresponding message returned by f.
+func WrapErrorFunc(err error, f func(err error) string) error {
+ if err == nil {
+ return nil
+ }
+ return wrapError(err, f(err))
+}
+
+func wrapError(err error, message string) *BaseError {
+ return &BaseError{message, baseError{err}}
+}
+
+var (
+ baseErrorType = reflect.TypeFor[*BaseError]()
+)
+
+func AsBaseError(err error, target **BaseError) bool {
+ v := reflect.ValueOf(err)
+ if !v.CanConvert(baseErrorType) {
+ return false
+ }
+
+ *target = v.Convert(baseErrorType).Interface().(*BaseError)
+ return true
+}
diff --git a/internal/fmsg/fmsg.go b/internal/fmsg/fmsg.go
new file mode 100644
index 00000000..40d34108
--- /dev/null
+++ b/internal/fmsg/fmsg.go
@@ -0,0 +1,2 @@
+// Package fmsg provides various functions for output messages.
+package fmsg