128 lines
2.5 KiB
Go
128 lines
2.5 KiB
Go
package errs
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"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
|
|
msg = er.msg + ": " + source.Error()
|
|
)
|
|
for unwrap := errors.Unwrap(source); unwrap != nil; source = unwrap {
|
|
originMsg := unwrap.Error()
|
|
// TODO: Test this!
|
|
if cut, found := strings.CutSuffix(msg, originMsg); found {
|
|
s.WriteString(cut)
|
|
msg = originMsg
|
|
} else {
|
|
s.WriteString(msg)
|
|
}
|
|
|
|
s.WriteString(": ")
|
|
|
|
unwrap = errors.Unwrap(unwrap)
|
|
}
|
|
return s.String()
|
|
}
|
|
|
|
func (er *Err) Message(msg string, args ...any) Error {
|
|
panic("not implemented") // TODO: Implement
|
|
}
|
|
|
|
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
|
|
}
|