Wednesday, 24 June 2020

Go Language: Errors


errors (standard package)

errors - The Go Programming Language

Go by Example: Errors

If function returns type error and we want to return error object with custom message:

return errors.New("Argument is nil: file")

To create an error with formatted message use fmt.Errorf:

err := fmt.Errorf("user %q (id %d) not found", name, id)


Example when type assertion is used to convert from error to some specific error type:
What is err.(*os.PathError) in Go?

Example:

fi, err := file.Stat()
if err != nil {
return 0, fmt.Errorf("Failed to access file %s", (err.(*os.PathError)).Path)
}


github.com/pkg/errors package


Go default package "errors" does not support capturing stack trace info at the moment when error is created. When the error is created somewhere deep on the stack, it can be returned from the chain of function calls to the main error handler where the only information which can be extracted is error text message, without its context. When such message appears in the log, it is difficult to find out where it came from, from which function. 

Example of the Go app log snippet:

...
Error: Bad status: 404 Not Found
Terminating with error: 1
Process exited with code 1


All we know from error message "Bad status: 404 Not Found" that some HTTP response returned 404 but we don't know which one and in which part of the code.

To capture stack trace at the moment when error gets created and later be able to print it out, we can use github.com/pkg/errors package.

errors package · pkg.go.dev

This article explains best practices and how you need to change our code in order to use this package efficiently:




Here are the changes in the code base that need to be done when switching from errors to github.com/pkg/errors package:

import (
"errors"
...
)

will be replaced with 

import (
        ...
"github.com/pkg/errors"
)

...so go.mod will contain something like:

github.com/pkg/errors v0.8.1


Error creation errors.New("...") will remain the same but 

fmt.Errorf("%s value is empty string", key)

will be replaced with 

errors.Errorf("%s value is empty string", key)


Instead of passing the original error and message:

if err := bg.foo(br, df); err != nil {
return err
}

...we can add a context info by adding a contextual error message (and still keeping the original one):

if err := bg.foo(br, df); err != nil {
return errors.Wrapf(err, "Fetching resource with ID = %s failed for entity with ID = %s", br.ResID, br.ID)
}


Instead of just printing the error message:

func LogAndExit(err error, code int) {
if err != nil {
log.Printf("Error: %s\nTerminating with error: %d", err.Error(), code)
os.Exit(code)
}
}

we can now print message AND stack trace:
 
func LogAndExit(err error, code int) {
if err != nil {
log.Printf("Error: %+v\nTerminating with error: %d", err, code)
os.Exit(code)
}
}

1 comment:

micheal pan said...

BE SMART AND BECOME RICH IN LESS THAN 3DAYS....It all depends on how fast 
you can be to get the new PROGRAMMED blank ATM card that is capable of
hacking into any ATM machine,anywhere in the world. I got to know about 
this BLANK ATM CARD when I was searching for job online about a month 
ago..It has really changed my life for good and now I can say I'm rich and 
I can never be poor again. The least money I get in a day with it is about 
$50,000.(fifty thousand USD) Every now and then I keeping pumping money 
into my account. Though is illegal,there is no risk of being caught 
,because it has been programmed in such a way that it is not traceable,it 
also has a technique that makes it impossible for the CCTVs to detect 
you..For details on how to get yours today, email the hackers on : (
atmmachinehackers1@gmail.com ). Tell your 
loved once too, and start to live large. That's the simple testimony of how 
my life changed for good...Love you all ...the email address again is ;
atmmachinehackers1@gmail.com