summaryrefslogtreecommitdiff
path: root/vendor/codeberg.org/gruf/go-errors/v2/errors.go
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2023-11-30 16:22:34 +0000
committerLibravatar GitHub <noreply@github.com>2023-11-30 16:22:34 +0000
commiteb170003b81504ba6eb85f950c223dc9eaf1cfca (patch)
treef1f9779e14875faa70f4db85a8cf19100633884d /vendor/codeberg.org/gruf/go-errors/v2/errors.go
parent[bugfix] always go through status parent dereferencing on isNew, even on data... (diff)
downloadgotosocial-eb170003b81504ba6eb85f950c223dc9eaf1cfca.tar.xz
[bugfix] return 400 Bad Request on more cases of malformed AS data (#2399)
Diffstat (limited to 'vendor/codeberg.org/gruf/go-errors/v2/errors.go')
-rw-r--r--vendor/codeberg.org/gruf/go-errors/v2/errors.go231
1 files changed, 221 insertions, 10 deletions
diff --git a/vendor/codeberg.org/gruf/go-errors/v2/errors.go b/vendor/codeberg.org/gruf/go-errors/v2/errors.go
index 2c4689151..d5f1a7ab1 100644
--- a/vendor/codeberg.org/gruf/go-errors/v2/errors.go
+++ b/vendor/codeberg.org/gruf/go-errors/v2/errors.go
@@ -1,37 +1,248 @@
package errors
import (
- "errors"
"fmt"
+ "runtime"
)
// New returns a new error created from message.
+//
+// Note this function cannot be inlined, to ensure expected
+// and consistent behaviour in setting trace / caller info.
+//
+//go:noinline
func New(msg string) error {
- return create(msg, nil)
+ var c caller
+ var t trace
+ if IncludesCaller {
+ pcs := make([]uintptr, 1)
+ _ = runtime.Callers(2, pcs)
+ fn := runtime.FuncForPC(pcs[0])
+ c.set(funcName(fn))
+ }
+ if IncludesStacktrace {
+ pcs := make([]uintptr, 10)
+ n := runtime.Callers(2, pcs)
+ iter := runtime.CallersFrames(pcs[:n])
+ t.set(gatherFrames(iter, n))
+ }
+ return &_errormsg{
+ cfn: c,
+ msg: msg,
+ trc: t,
+ }
}
// Newf returns a new error created from message format and args.
+//
+// Note this function cannot be inlined, to ensure expected
+// and consistent behaviour in setting trace / caller info.
+//
+//go:noinline
func Newf(msgf string, args ...interface{}) error {
- return create(fmt.Sprintf(msgf, args...), nil)
+ var c caller
+ var t trace
+ if IncludesCaller {
+ pcs := make([]uintptr, 1)
+ _ = runtime.Callers(2, pcs)
+ fn := runtime.FuncForPC(pcs[0])
+ c.set(funcName(fn))
+ }
+ if IncludesStacktrace {
+ pcs := make([]uintptr, 10)
+ n := runtime.Callers(2, pcs)
+ iter := runtime.CallersFrames(pcs[:n])
+ t.set(gatherFrames(iter, n))
+ }
+ return &_errormsg{
+ cfn: c,
+ msg: fmt.Sprintf(msgf, args...),
+ trc: t,
+ }
+}
+
+// NewAt returns a new error created, skipping 'skip'
+// frames for trace / caller information, from message.
+//
+// Note this function cannot be inlined, to ensure expected
+// and consistent behaviour in setting trace / caller info.
+//
+//go:noinline
+func NewAt(skip int, msg string) error {
+ var c caller
+ var t trace
+ if IncludesCaller {
+ pcs := make([]uintptr, 1)
+ _ = runtime.Callers(skip+1, pcs)
+ fn := runtime.FuncForPC(pcs[0])
+ c.set(funcName(fn))
+ }
+ if IncludesStacktrace {
+ pcs := make([]uintptr, 10)
+ n := runtime.Callers(skip+1, pcs)
+ iter := runtime.CallersFrames(pcs[:n])
+ t.set(gatherFrames(iter, n))
+ }
+ return &_errormsg{
+ cfn: c,
+ msg: msg,
+ trc: t,
+ }
}
// Wrap will wrap supplied error within a new error created from message.
+//
+// Note this function cannot be inlined, to ensure expected
+// and consistent behaviour in setting trace / caller info.
+//
+//go:noinline
func Wrap(err error, msg string) error {
- return create(msg, err)
+ if err == nil {
+ panic("cannot wrap nil error")
+ }
+ var c caller
+ var t trace
+ if IncludesCaller {
+ pcs := make([]uintptr, 1)
+ _ = runtime.Callers(2, pcs)
+ fn := runtime.FuncForPC(pcs[0])
+ c.set(funcName(fn))
+ }
+ if IncludesStacktrace {
+ pcs := make([]uintptr, 10)
+ n := runtime.Callers(2, pcs)
+ iter := runtime.CallersFrames(pcs[:n])
+ t.set(gatherFrames(iter, n))
+ }
+ return &_errorwrap{
+ cfn: c,
+ msg: msg,
+ err: err,
+ trc: t,
+ }
}
// Wrapf will wrap supplied error within a new error created from message format and args.
+//
+// Note this function cannot be inlined, to ensure expected
+// and consistent behaviour in setting trace / caller info.
+//
+//go:noinline
func Wrapf(err error, msgf string, args ...interface{}) error {
- return create(fmt.Sprintf(msgf, args...), err)
+ if err == nil {
+ panic("cannot wrap nil error")
+ }
+ var c caller
+ var t trace
+ if IncludesCaller {
+ pcs := make([]uintptr, 1)
+ _ = runtime.Callers(2, pcs)
+ fn := runtime.FuncForPC(pcs[0])
+ c.set(funcName(fn))
+ }
+ if IncludesStacktrace {
+ pcs := make([]uintptr, 10)
+ n := runtime.Callers(2, pcs)
+ iter := runtime.CallersFrames(pcs[:n])
+ t.set(gatherFrames(iter, n))
+ }
+ return &_errorwrap{
+ cfn: c,
+ msg: fmt.Sprintf(msgf, args...),
+ err: err,
+ trc: t,
+ }
+}
+
+// WrapAt wraps error within new error created from message,
+// skipping 'skip' frames for trace / caller information.
+//
+// Note this function cannot be inlined, to ensure expected
+// and consistent behaviour in setting trace / caller info.
+//
+//go:noinline
+func WrapAt(skip int, err error, msg string) error {
+ if err == nil {
+ panic("cannot wrap nil error")
+ }
+ var c caller
+ var t trace
+ if IncludesCaller {
+ pcs := make([]uintptr, 1)
+ _ = runtime.Callers(skip+1, pcs)
+ fn := runtime.FuncForPC(pcs[0])
+ c.set(funcName(fn))
+ }
+ if IncludesStacktrace {
+ pcs := make([]uintptr, 10)
+ n := runtime.Callers(skip+1, pcs)
+ iter := runtime.CallersFrames(pcs[:n])
+ t.set(gatherFrames(iter, n))
+ }
+ return &_errorwrap{
+ cfn: c,
+ msg: msg,
+ err: err,
+ trc: t,
+ }
}
// Stacktrace fetches first stored stacktrace of callers from error chain.
func Stacktrace(err error) Callers {
- var e interface {
- Stacktrace() Callers
- }
- if !errors.As(err, &e) {
+ if !IncludesStacktrace {
+ // compile-time check
return nil
}
- return e.Stacktrace()
+ if e := AsV2[*_errormsg](err); err != nil {
+ return e.trc.value()
+ }
+ if e := AsV2[*_errorwrap](err); err != nil {
+ return e.trc.value()
+ }
+ return nil
+}
+
+type _errormsg struct {
+ cfn caller
+ msg string
+ trc trace
+}
+
+func (err *_errormsg) Error() string {
+ if IncludesCaller {
+ fn := err.cfn.value()
+ return fn + " " + err.msg
+ } else {
+ return err.msg
+ }
+}
+
+func (err *_errormsg) Is(other error) bool {
+ oerr, ok := other.(*_errormsg)
+ return ok && oerr.msg == err.msg
+}
+
+type _errorwrap struct {
+ cfn caller
+ msg string
+ err error // wrapped
+ trc trace
+}
+
+func (err *_errorwrap) Error() string {
+ if IncludesCaller {
+ fn := err.cfn.value()
+ return fn + " " + err.msg + ": " + err.err.Error()
+ } else {
+ return err.msg + ": " + err.err.Error()
+ }
+}
+
+func (err *_errorwrap) Is(other error) bool {
+ oerr, ok := other.(*_errorwrap)
+ return ok && oerr.msg == err.msg
+}
+
+func (err *_errorwrap) Unwrap() error {
+ return err.err
}