Increasing the informational content of errors in Go -

    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 kind of `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: → GitHub

    golang error output

    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 structure will remain the same and will not be overwritten, this is convenient if it is not known whether the error already has a standard structure or not.

    The code might look something like this:

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

    Displaying the frame

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

    1) Display error text and framerays:


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


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


    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)


    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 with the source code right away.
    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 in 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.

    Also popular now: