获取返回函数的行号

Is it possible to get the line number on which a function returned from the calling scope?

Example:

func callee() error {
  if cond {
    return errors.New("whoops!")
  }
  return nil
}

func caller() {
  // Possible to retrieve the line number of callee return here?
  callee()
}

I assume that's not possible, since it should be already removed from the stack, but maybe it's still cached somewhere?

The use case is that I have a HTTP handler and I'd like to log the line and filename on which the error was returned, without having to litter the code.

AFAIK, it is not possible to automatically acquire the line where the last return was executed.

However, with a small helper one can have:

package main

import (
        "fmt"
        "runtime"
)

func here(s string, args ...interface{}) error {
        _, fname, fline, _ := runtime.Caller(1)
        h := fmt.Sprintf("%s:%d: ", fname, fline)
        return fmt.Errorf(h+s, args...)
}

func foo(i int) error {
        if i == 2 {
                return here("cannot handle %d", i) // line 16
        }

        if i%3 == 0 {
                return here("also cannot handle %d", i) // line 20
        }

        return nil
}

func main() {
        fmt.Println(foo(2))
        fmt.Println(foo(3))
        fmt.Println(foo(4))
}

Playground


Output:

/tmpfs/gosandbox-92c2a0f2_32bdf9d9_3c7d2a0a_80ba8510_f68d9721/prog.go:16: cannot handle 2
/tmpfs/gosandbox-92c2a0f2_32bdf9d9_3c7d2a0a_80ba8510_f68d9721/prog.go:20: also cannot handle 3
<nil>