The Hyperledger Fabric error handling framework can be found in the source
repository under common/errors. It defines a new type of error,
CallStackError, to use in place of the standard error type provided by Go.

A CallStackError consists of the following:

Component code - a name for the general area of the code that is generating
the error. Component codes should consist of three uppercase letters. Numerics
and special characters are not allowed. A set of component codes is defined
in common/errors/codes.go

Reason code - a short code to help identify the reason the error occurred.
Reason codes should consist of three numeric values. Letters and special
characters are not allowed. A set of reason codes is defined in
common/error/codes.go

Error message - the text that describes the error. This is the same as the
input provided to fmt.Errorf() and Errors.New(). If an error has been
wrapped into the current error, its message will be appended.

Callstack - the callstack at the time the error is created. If an error has
been wrapped into the current error, its error message and callstack will be
appended to retain the context of the wrapped error.

The new error handling framework should be used in place of all calls to
fmt.Errorf() or Errors.new(). Using this framework will provide error
codes to check against as well as the option to generate a callstack that will be
appended to the error message.

Using the framework is simple and will only require an easy tweak to your code.

First, you’ll need to import github.com/hyperledger/fabric/common/errors into
any file that uses this framework.

Let’s take the following as an example from core/chaincode/chaincode_support.go:

err=fmt.Errorf("Error starting container: %s",err)

For this error, we will simply call the constructor for Error and pass a
component code, reason code, followed by the error message. At the end, we
then call the WrapError() function, passing along the error itself.

If it is some sort of best effort thing you are doing, you should log the
error and ignore it.

If you are servicing a user request, you should log the error and return it.

If the error comes from elsewhere, you have the choice to wrap the error
or not. Typically, it’s best to not wrap the error and simply return
it as is. However, for certain cases where a utility function is called,
wrapping the error with a new component and reason code can help an end user
understand where the error is really occurring without inspecting the callstack.

A panic should be handled within the same layer by throwing an internal error
code/start a recovery process and should not be allowed to propagate to other
packages.