It is recommended that go+ further enhance the stack information when errors occur.
Proposal
if my code like this : main->add3->add2->add
` import ( "strconv" "runtime" "strings" )
func add3(x, y string) (int, error) { return add2(x, y ) }
func add2(x, y string) (int, error) { return add(x, y ) }
func add(x, y string) (int, error) { return strconv.atoi(x)? + strconv.atoi(y)?, nil }
sum, err := add3("9999", "kkkk") _, _ = sum, err println err println "this is ending"
`
this is the original output:
==> errors stack a: . main.add3() . bin/a.gop:16 strconv.atoi(y)
but I hope the error output add the info like this:
main.add . bin/a.gop:16 main.add2 . bin/a.gop:12 main.add3 . bin/a.gop:7 main.main() . bin/a.gop:19
here is my modify in source code:
...\go\pkg\mod\github.com\qiniu\[email protected]\errors\errors.go
The added content is in bold font :
// Frame represents an error frame. type Frame struct { Err error Func string Args []interface{} Code string File string Line int Stack []byte }
// NewFrame creates a new error frame. func NewFrame(err error, code, file string, line int, fn string, args ...interface{}) *Frame { stack := make([]byte, 2048) length := runtime.Stack(stack, false) return &Frame{Err: err, Func: fn, Args: args, Code: code, File: file, Line: line , Stack: stack[:length] } }
func errorDetail(b []byte, p *Frame) []byte { if f, ok := p.Err.(*Frame); ok { //fmt.Println( "sqhua errors.go Debug2: ", p ) b = errorDetail(b, f) } else { b = append(b, p.Err.Error()...) b = append(b, "\n\n==> errors stack a:\n"...) } b = append(b, p.Func...) b = append(b, '(') b = argsDetail(b, p.Args) b = append(b, ")\n\t"...) b = append(b, p.File...) b = append(b, ':') b = strconv.AppendInt(b, int64(p.Line), 10) b = append(b, ' ') b = append(b, p.Code...) b = append(b, '\n') b = append(b, '\n') b = append(b, parseStack( 20, string(p.Stack))...) b = append(b, '\n') return b }
func parseStack(n int, stack string) string { stackLines := strings.Split(stack, "\n") var parsedStack string for i, line := range stackLines { if i < 3 { //skip the gop inter func call continue } if i >= n { break } parsedStack = parsedStack + "\n" + line } return parsedStack }
Background
Currently, go+ only outputs the line of code where the error occurred, but not the call chain.
Workarounds
when coding, this feature is useful, and help C# or Java player to easy use go+
/
If the default output is detailed stack information, it may also result in too much information. When developing in Java, it was also very painful to look at the log files when using frameworks like Spring with deep call stacks. Therefore, it can be considered to add a stack_level configuration item to indicate the depth of the output, with a default value of 0, which is the current gop's output_mode.
进一步的建议: 如果默认输出了详细stack信息,也可能造成信息过多。之前做Java开发时,用到Spring等调用栈过深的框架时,看那些Log日志也很头痛。因此可以考虑在哪加个stack_level配置项,表示要输出的深度,默认是0,也就是当前gop的输出方式。