mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-01 02:30:48 -05:00
Bumps [github.com/gookit/config/v2](https://github.com/gookit/config) from 2.2.5 to 2.2.6. - [Release notes](https://github.com/gookit/config/releases) - [Commits](https://github.com/gookit/config/compare/v2.2.5...v2.2.6) --- updated-dependencies: - dependency-name: github.com/gookit/config/v2 dependency-version: 2.2.6 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <support@github.com>
188 lines
3.7 KiB
Go
188 lines
3.7 KiB
Go
package errorx
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strconv"
|
|
)
|
|
|
|
// stack represents a stack of program counters.
|
|
type stack []uintptr
|
|
|
|
// Format stack trace
|
|
func (s *stack) Format(fs fmt.State, verb rune) {
|
|
switch verb {
|
|
// case 'v', 's':
|
|
case 'v':
|
|
_, _ = s.WriteTo(fs)
|
|
}
|
|
}
|
|
|
|
// StackLen for error
|
|
func (s *stack) StackLen() int {
|
|
return len(*s)
|
|
}
|
|
|
|
// WriteTo for error
|
|
func (s *stack) WriteTo(w io.Writer) (int64, error) {
|
|
if len(*s) == 0 {
|
|
return 0, nil
|
|
}
|
|
|
|
nn, _ := w.Write([]byte("\nSTACK:\n"))
|
|
for _, pc := range *s {
|
|
// For historical reasons if pc is interpreted as a uintptr
|
|
// its value represents the program counter + 1.
|
|
fc := runtime.FuncForPC(pc - 1)
|
|
if fc == nil {
|
|
continue
|
|
}
|
|
|
|
// file eg: workspace/godev/gookit/goutil/errorx/errorx_test.go
|
|
file, line := fc.FileLine(pc - 1)
|
|
// f.Name() eg: github.com/gookit/goutil/errorx_test.TestWithPrev()
|
|
location := fc.Name() + "()\n " + file + ":" + strconv.Itoa(line) + "\n"
|
|
|
|
n, _ := w.Write([]byte(location))
|
|
nn += n
|
|
}
|
|
|
|
return int64(nn), nil
|
|
}
|
|
|
|
// String format to string
|
|
func (s *stack) String() string {
|
|
var buf bytes.Buffer
|
|
_, _ = s.WriteTo(&buf)
|
|
return buf.String()
|
|
}
|
|
|
|
// StackFrames stack frame list
|
|
func (s *stack) StackFrames() *runtime.Frames {
|
|
return runtime.CallersFrames(*s)
|
|
}
|
|
|
|
// CallerPC the caller PC value in the stack. it is first frame.
|
|
func (s *stack) CallerPC() uintptr {
|
|
if len(*s) == 0 {
|
|
return 0
|
|
}
|
|
|
|
// For historical reasons if pc is interpreted as a uintptr
|
|
// its value represents the program counter + 1.
|
|
return (*s)[0] - 1
|
|
}
|
|
|
|
/*************************************************************
|
|
* For error caller func
|
|
*************************************************************/
|
|
|
|
// Func struct
|
|
type Func struct {
|
|
*runtime.Func
|
|
pc uintptr
|
|
}
|
|
|
|
// FuncForPC create.
|
|
func FuncForPC(pc uintptr) *Func {
|
|
fc := runtime.FuncForPC(pc)
|
|
if fc == nil {
|
|
return nil
|
|
}
|
|
|
|
return &Func{
|
|
pc: pc,
|
|
Func: fc,
|
|
}
|
|
}
|
|
|
|
// FileLine returns the file name and line number of the source code
|
|
func (f *Func) FileLine() (file string, line int) {
|
|
return f.Func.FileLine(f.pc)
|
|
}
|
|
|
|
// Location simple location info for the func
|
|
//
|
|
// Returns eg:
|
|
//
|
|
// "github.com/gookit/goutil/errorx_test.TestWithPrev(), errorx_test.go:34"
|
|
func (f *Func) Location() string {
|
|
file, line := f.FileLine()
|
|
|
|
return f.Name() + "(), " + filepath.Base(file) + ":" + strconv.Itoa(line)
|
|
}
|
|
|
|
// String of the func
|
|
//
|
|
// Returns eg:
|
|
//
|
|
// github.com/gookit/goutil/errorx_test.TestWithPrev()
|
|
// At /path/to/github.com/gookit/goutil/errorx_test.go:34
|
|
func (f *Func) String() string {
|
|
file, line := f.FileLine()
|
|
|
|
return f.Name() + "()\n At " + file + ":" + strconv.Itoa(line)
|
|
}
|
|
|
|
// MarshalText handle
|
|
func (f *Func) MarshalText() ([]byte, error) {
|
|
return []byte(f.String()), nil
|
|
}
|
|
|
|
/*************************************************************
|
|
* helper func for callers stacks
|
|
*************************************************************/
|
|
|
|
// ErrStackOpt struct
|
|
type ErrStackOpt struct {
|
|
SkipDepth int
|
|
TraceDepth int
|
|
}
|
|
|
|
// default option
|
|
var stdOpt = newErrOpt()
|
|
|
|
// ResetStdOpt config
|
|
func ResetStdOpt() {
|
|
stdOpt = newErrOpt()
|
|
}
|
|
|
|
func newErrOpt() *ErrStackOpt {
|
|
return &ErrStackOpt{
|
|
SkipDepth: 3,
|
|
TraceDepth: 8,
|
|
}
|
|
}
|
|
|
|
// Config the stdOpt setting
|
|
func Config(fns ...func(opt *ErrStackOpt)) {
|
|
for _, fn := range fns {
|
|
fn(stdOpt)
|
|
}
|
|
}
|
|
|
|
// SkipDepth setting
|
|
func SkipDepth(skipDepth int) func(opt *ErrStackOpt) {
|
|
return func(opt *ErrStackOpt) {
|
|
opt.SkipDepth = skipDepth
|
|
}
|
|
}
|
|
|
|
// TraceDepth setting
|
|
func TraceDepth(traceDepth int) func(opt *ErrStackOpt) {
|
|
return func(opt *ErrStackOpt) {
|
|
opt.TraceDepth = traceDepth
|
|
}
|
|
}
|
|
|
|
func callersStack(skip, depth int) *stack {
|
|
pcs := make([]uintptr, depth)
|
|
num := runtime.Callers(skip, pcs[:])
|
|
|
|
var st stack = pcs[0:num]
|
|
return &st
|
|
}
|