Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you get a Golang program to print the line number of the error it just called?

I was trying to throw errors in my Golang program with log.Fatal but, log.Fatal does not also print the line where the log.Fatal was ran. Is there no way of getting access to the line number that called log.Fatal? i.e. is there a way to get the line number when throwing an error?

I was trying to google this but was unsure how. The best thing I could get was printing the stack trace, which I guess is good but might be a little too much. I also don't want to write debug.PrintStack() every time I need the line number, I am just surprised there isn't any built in function for this like log.FatalStackTrace() or something that isn't costume.

Also, the reason I do not want to make my own debugging/error handling stuff is because I don't want people to have to learn how to use my special costume handling code. I just want something standard where people can read my code later and be like

"ah ok, so its throwing an error and doing X..."

The less people have to learn about my code the better :)

like image 664
Charlie Parker Avatar asked Jul 17 '14 16:07

Charlie Parker


People also ask

How do you wrap an error in Go?

It does not matter that the error is wrapped. A simple comparison if err == ErrorInternal would give false in this case, so it is generally a better idea to use the errors.Is() function to compare errors equality. Then, we unwrap the error using the errors. Unwrap() and print it to the standard output.

What is Golang error type?

error is a built-in interface type in Go. An error variable represents any value that can describe itself as a string . The following is the error interface declaration: type error interface { Error() string.

What is Golang error handling?

In summary, here's the gist of what was covered here: Errors in Go are just lightweight pieces of data that implement the Error interface. Predefined errors will improve signaling, allowing us to check which error occurred. Wrap errors to add enough context to trace through function calls (similar to a stack trace)


2 Answers

You can set the Flags on either a custom Logger, or the default to include Llongfile or Lshortfile

// to change the flags on the default logger log.SetFlags(log.LstdFlags | log.Lshortfile) 
like image 151
JimB Avatar answered Oct 27 '22 23:10

JimB


Short version, there's nothing directly built in, however you can implement it with a minimal learning curve using runtime.Caller

func HandleError(err error) (b bool) {     if err != nil {         // notice that we're using 1, so it will actually log where         // the error happened, 0 = this function, we don't want that.         _, filename, line, _ := runtime.Caller(1)         log.Printf("[error] %s:%d %v", filename, line, err)         b = true     }     return }  //this logs the function name as well. func FancyHandleError(err error) (b bool) {     if err != nil {         // notice that we're using 1, so it will actually log the where         // the error happened, 0 = this function, we don't want that.         pc, filename, line, _ := runtime.Caller(1)          log.Printf("[error] in %s[%s:%d] %v", runtime.FuncForPC(pc).Name(), filename, line, err)         b = true     }     return }  func main() {     if FancyHandleError(fmt.Errorf("it's the end of the world")) {         log.Print("stuff")     } } 

playground

like image 29
OneOfOne Avatar answered Oct 27 '22 21:10

OneOfOne