diff options
author | 2022-05-08 19:49:45 +0200 | |
---|---|---|
committer | 2022-05-08 18:49:45 +0100 | |
commit | 5004e0a9da665ccc0e18cd4075ee636641b71f0a (patch) | |
tree | b7c8269b954ced61afa9fffd7305bd88acca6f8e /vendor/codeberg.org/gruf/go-errors/v2/callers.go | |
parent | [bugfix] Fix existing bio text showing as HTML (#531) (diff) | |
download | gotosocial-5004e0a9da665ccc0e18cd4075ee636641b71f0a.tar.xz |
[bugfix] Fix remote media pruning failing if media already gone (#548)
* fix error check of prune to allow missing files
* update go-store library, add test for pruning item with db entry but no file
Signed-off-by: kim <grufwub@gmail.com>
* remove now-unneccessary error check
Signed-off-by: kim <grufwub@gmail.com>
Co-authored-by: kim <grufwub@gmail.com>
Diffstat (limited to 'vendor/codeberg.org/gruf/go-errors/v2/callers.go')
-rw-r--r-- | vendor/codeberg.org/gruf/go-errors/v2/callers.go | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/vendor/codeberg.org/gruf/go-errors/v2/callers.go b/vendor/codeberg.org/gruf/go-errors/v2/callers.go new file mode 100644 index 000000000..77a2c1c1b --- /dev/null +++ b/vendor/codeberg.org/gruf/go-errors/v2/callers.go @@ -0,0 +1,102 @@ +package errors + +import ( + "encoding/json" + "runtime" + "strconv" + "strings" + "unsafe" +) + +// Callers is a stacktrace of caller PCs. +type Callers []uintptr + +// GetCallers returns a Callers slice of PCs, of at most 'depth'. +func GetCallers(skip int, depth int) Callers { + rpc := make([]uintptr, depth) + n := runtime.Callers(skip+1, rpc) + return Callers(rpc[0:n]) +} + +// Frames fetches runtime frames for a slice of caller PCs. +func (f Callers) Frames() []runtime.Frame { + // Allocate expected frames slice + frames := make([]runtime.Frame, 0, len(f)) + + // Get frames iterator for PCs + iter := runtime.CallersFrames(f) + + for { + // Get next frame in iter + frame, ok := iter.Next() + if !ok { + break + } + + // Append to frames slice + frames = append(frames, frame) + } + + return frames +} + +// MarshalJSON implements json.Marshaler to provide an easy, simply default. +func (f Callers) MarshalJSON() ([]byte, error) { + // JSON-able frame type + type frame struct { + Func string `json:"func"` + File string `json:"file"` + Line int `json:"line"` + } + + // Allocate expected frames slice + frames := make([]frame, 0, len(f)) + + // Get frames iterator for PCs + iter := runtime.CallersFrames(f) + + for { + // Get next frame + f, ok := iter.Next() + if !ok { + break + } + + // Append to frames slice + frames = append(frames, frame{ + Func: funcname(f.Function), + File: f.File, + Line: f.Line, + }) + } + + // marshal converted frames + return json.Marshal(frames) +} + +// String will return a simple string representation of receiving Callers slice. +func (f Callers) String() string { + // Guess-timate to reduce allocs + buf := make([]byte, 0, 64*len(f)) + + // Convert to frames + frames := f.Frames() + + for i := 0; i < len(frames); i++ { + frame := frames[i] + + // Append formatted caller info + funcname := funcname(frame.Function) + buf = append(buf, funcname+"()\n\t"+frame.File+":"...) + buf = strconv.AppendInt(buf, int64(frame.Line), 10) + buf = append(buf, '\n') + } + + return *(*string)(unsafe.Pointer(&buf)) +} + +// funcname splits a function name with pkg from its path prefix. +func funcname(name string) string { + i := strings.LastIndex(name, "/") + return name[i+1:] +} |