📜 ⬆️ ⬇️

Increasing the informational content of errors in Go - github.com/ztrue/tracerr

After many years of experience working with php and js, I’m used to having the error in the errors and looking at the place where the error occurred directly from the error report. After reseeding Go a couple of years ago, I was somewhat surprised that there are other rules in Go and you need to guess the setrays for some line of the ʻinvalid character` type. And if it happened on the prode and it is not known how to reproduce it, then it turned into a whole attraction.

Since I am sure that not one suffered from this, I made a package that can do this:

golang error output

GitHub

All he does is:

  1. Adds to the error of the error.
  2. Displays the template and source code fragments where this error occurred (in the presence of source codes, of course).

Add feature


You can create an error with the model in one of several ways:

// создать новую err := tracerr.New("some error") // можно методом Errorf, который работает так же, как и fmt.Errorf err := tracerr.Errorf("some error %d", num) // или обернуть существующую ошибку, добавив ей стектрейс err = tracerr.Wrap(err) 

When the error is re-wrapped, the spectra will remain the same and will not be overwritten, this is convenient if it is not known whether the error already has a spectra or not.

The code might look something like this:

 func decodeFile(path string, data interface{}) error { b, err := ioutil.ReadFile(path) if err != nil { return tracerr.Wrap(err) } err = json.Unmarshal(b, data) // если err = nil, то останется nil return tracerr.Wrap(err) } 

Displaying the frame


After the error through 100500 if err != nil { return err } returns to the Motherland in main() (or where it is processed), most likely you will want to display or log it.
There are several options for this: all work like Print (prints text) or Sprint (returns text):

1) Display the text of the error and the frame:

 tracerr.Print(err) 

2) Display the error text, the spectra and a fragment of the source code (6 lines by default):

 tracerr.PrintSource(err) 

3) Same, but in color, usually more informative:

 tracerr.PrintSourceColor(err) 

4) You can pass as a parameter how many lines of code to display:

 tracerr.PrintSource(err, 9) tracerr.PrintSourceColor(err, 9) 

5) Or transfer 2 optional parameters, how many before and how many after the line with an error to display:

 tracerr.PrintSource(err, 5, 2) tracerr.PrintSourceColor(err, 5, 2) 

Questions


I have already received some feedback, so I will allow myself to answer in advance some questions that have already been asked.

Q: Is this only for debugging? There is a debugger.
A: This is not only suitable for debugging, you can log errors with information about the setrace, and even with fragments of source codes, in the sale, as in my experience, this will greatly simplify later to disassemble these errors.

Q: There is a super pkg / errors package, why not use it?
A: Yes, I used it quite well and was glad, but it didn’t suit me for these reasons:
1) There is no easy way to display the template right from the source.
2) When re-wrapping the error (for example, one level higher), the grid-frame is overwritten by less informative.
3) With each wrapping, it is necessary to transfer an additional text of the error, which seems to me to be some overhead-leader when writing / reading code.

Q: In Go, errors are not exceptions, and you can't do that at all.
A: I agree, in Go, errors are not exceptions. If it is more convenient for you to process thousands of if err != nil { return err } some other way - this is your choice, of course. You can only wrap errors that you treat as exceptions.

Q: Stektreys adds overhead to performance.
A: Yes, it adds, but this is relevant only for places where errors are created in large quantities, just do not add a glass trace there if it is critical (I am sure that in most cases this overhead is insignificant).

In general, I hope this package will make your gofer life somewhat easier, I will be glad to any feedback, thanks.

Source: https://habr.com/ru/post/440008/