-
Notifications
You must be signed in to change notification settings - Fork 0
/
trace.go
69 lines (59 loc) · 1.47 KB
/
trace.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// Copyright (c) 2023 William Dode. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
package werr
import (
"fmt"
"path/filepath"
"runtime"
"strings"
)
// Allow trace or disable for the project
var WithTrace = true
// Show full path instead of basename
var WithFullPath = false
// Show full name instead of [1:]
var WithFullName = false
// Wrapf returns formated error with trace and : %w
func Wrapf(err error, s string, vals ...any) error {
if err == nil {
return nil
}
vals = append(vals, err)
return tracef(2, s+": %w", vals...)
}
// Wrap returns error with trace and %w
func Wrap(err error) error {
if err == nil {
return nil
}
return tracef(2, "%w", err)
}
// Errorf is like fmt.Errorf with trace
// wrap if %w
// not wrap if %v
func Errorf(s string, vals ...any) error {
return tracef(2, s, vals...)
}
// New is like errors.New with trace
func New(s string) error {
return tracef(2, s)
}
// tracef add trace before calling fmt.Errorf
func tracef(skip int, s string, vals ...any) error {
pc, file, line, ok := runtime.Caller(skip)
if ok && WithTrace {
name := runtime.FuncForPC(pc).Name()
if !WithFullName {
splt := strings.Split(runtime.FuncForPC(pc).Name(), "/")
name = strings.Join(splt[1:], "/")
}
path := file
if !WithFullPath {
path = filepath.Base(file)
}
info := fmt.Sprintf("\n> %s() %s:%d\n",
name, path, line)
s = info + strings.TrimSpace(s)
}
return fmt.Errorf(s, vals...)
}