Redmage/errs/errs.go

139 lines
2.7 KiB
Go
Raw Normal View History

2024-04-06 01:22:00 +07:00
package errs
import (
"context"
"errors"
2024-04-06 01:33:03 +07:00
"fmt"
2024-04-06 01:22:00 +07:00
"log/slog"
"os"
"reflect"
"runtime"
"strings"
)
type Error interface {
error
Message(msg string, args ...any) Error
GetMessage() string
Code(status int) Error
GetCode() int
Caller(pc uintptr) Error
GetCaller() uintptr
Details(...any) Error
GetDetails() []any
Log(ctx context.Context) Error
}
var _ Error = (*Err)(nil)
type Err struct {
msg string
code int
caller uintptr
details []any
origin error
}
func (er *Err) LogValue() slog.Value {
values := make([]slog.Attr, 0, 5)
if er.msg != "" {
values = append(values, slog.String("message", er.msg))
}
if er.code != 0 {
values = append(values, slog.Int("code", er.code))
}
if er.caller != 0 {
frame, _ := runtime.CallersFrames([]uintptr{er.caller}).Next()
split := strings.Split(frame.Function, string(os.PathSeparator))
fnName := split[len(split)-1]
values = append(values, slog.Group("origin",
slog.String("file", frame.File),
slog.Int("line", frame.Line),
slog.String("function", fnName),
))
}
if len(er.details) > 0 {
values = append(values, slog.Group("details", er.details...))
}
values = append(values, slog.Group("error",
slog.String("type", reflect.TypeOf(er.origin).String()),
slog.Any("data", er.origin),
))
return slog.GroupValue(values...)
}
func (er *Err) Error() string {
var (
s = strings.Builder{}
source = er.origin
2024-04-06 01:33:03 +07:00
msg = source.Error()
unwrap = errors.Unwrap(source)
2024-04-06 01:22:00 +07:00
)
2024-04-06 01:33:03 +07:00
if unwrap == nil {
if er.msg != "" {
s.WriteString(er.msg)
s.WriteString(": ")
}
s.WriteString(msg)
return s.String()
}
2024-04-06 01:22:00 +07:00
for unwrap := errors.Unwrap(source); unwrap != nil; source = unwrap {
originMsg := unwrap.Error()
2024-04-06 01:33:03 +07:00
var write string
2024-04-06 01:22:00 +07:00
if cut, found := strings.CutSuffix(msg, originMsg); found {
2024-04-06 01:33:03 +07:00
write = cut
2024-04-06 01:22:00 +07:00
} else {
2024-04-06 01:33:03 +07:00
write = msg
}
msg = originMsg
if write != "" {
s.WriteString(write)
s.WriteString(": ")
2024-04-06 01:22:00 +07:00
}
}
return s.String()
}
func (er *Err) Message(msg string, args ...any) Error {
2024-04-06 01:33:03 +07:00
er.msg = fmt.Sprintf(msg, args...)
return er
2024-04-06 01:22:00 +07:00
}
func (er *Err) GetMessage() string {
panic("not implemented") // TODO: Implement
}
func (er *Err) Code(status int) Error {
panic("not implemented") // TODO: Implement
}
func (er *Err) GetCode() int {
panic("not implemented") // TODO: Implement
}
func (er *Err) Caller(pc uintptr) Error {
panic("not implemented") // TODO: Implement
}
func (er *Err) GetCaller() uintptr {
panic("not implemented") // TODO: Implement
}
func (er *Err) Details(_ ...any) Error {
panic("not implemented") // TODO: Implement
}
func (er *Err) GetDetails() []any {
panic("not implemented") // TODO: Implement
}
func (er *Err) Log(ctx context.Context) Error {
panic("not implemented") // TODO: Implement
}