...
1 package errors
2
3 import (
4 "fmt"
5 "runtime"
6
7 "golang.conradwood.net/go-easyops/errors/shared"
8 "strings"
9 )
10
11 type stacktrace struct {
12 frames *runtime.Frames
13 positions []*shared.StackPos
14 }
15
16
17 func callingFunction() (string, *stacktrace) {
18 pc := make([]uintptr, 128)
19 num := runtime.Callers(0, pc)
20 if num == 0 {
21 return "[no caller]", nil
22 }
23 pc = pc[:num]
24 frames := runtime.CallersFrames(pc)
25 st := &stacktrace{frames: frames}
26 res := "[unidentifiable caller]"
27 more := true
28 var frame runtime.Frame
29 stop := false
30 for {
31
32 if !more {
33 break
34 }
35 frame, more = frames.Next()
36 pos := &shared.StackPos{Function: frame.Function, Line: frame.Line, Filename: frame.File}
37 st.positions = append(st.positions, pos)
38
39
40
41
42
43
44 if strings.Contains(frame.File, "runtime/") {
45 continue
46 }
47 if strings.Contains(frame.Function, "golang.conradwood.net/go-easyops/errors") {
48 continue
49 }
50
51 name := frame.Function
52 n := strings.LastIndex(name, ".")
53 if n != -1 {
54 name = name[n+1:] + "()"
55 }
56 fname := frame.File
57 n = strings.LastIndex(fname, "/src/")
58 if n != -1 {
59 fname = fname[n+5:]
60 }
61 if !stop {
62 res = fmt.Sprintf("%s in %s:%d", name, fname, frame.Line)
63 }
64 stop = true
65
66
67 }
68 return res, st
69 }
70
71 func (st *stacktrace) Positions() []*shared.StackPos {
72 return st.positions
73 }
74
View as plain text