github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/docs/source/error-handling.rst (about)

     1  Error handling
     2  ==============
     3  
     4  General Overview
     5  ----------------
     6  The Hyperledger Fabric error handling framework can be found in the source
     7  repository under **common/errors**. It defines a new type of error,
     8  CallStackError, to use in place of the standard error type provided by Go.
     9  
    10  A CallStackError consists of the following:
    11  
    12  - Component code - a name for the general area of the code that is generating
    13    the error. Component codes should consist of three uppercase letters. Numerics
    14    and special characters are not allowed. A set of component codes is defined
    15    in common/errors/codes.go
    16  - Reason code - a short code to help identify the reason the error occurred.
    17    Reason codes should consist of three numeric values. Letters and special
    18    characters are not allowed. A set of reason codes is defined in
    19    common/error/codes.go
    20  - Error code - the component code and reason code separated by a colon,
    21    e.g. MSP:404
    22  - Error message - the text that describes the error. This is the same as the
    23    input provided to ``fmt.Errorf()`` and ``Errors.New()``. If an error has been
    24    wrapped into the current error, its message will be appended.
    25  - Callstack - the callstack at the time the error is created. If an error has
    26    been wrapped into the current error, its error message and callstack will be
    27    appended to retain the context of the wrapped error.
    28  
    29  The CallStackError interface exposes the following functions:
    30  
    31  - Error() - returns the error message with callstack appended
    32  - Message() - returns the error message (without callstack appended)
    33  - GetComponentCode() - returns the 3-character component code
    34  - GetReasonCode() - returns the 3-digit reason code
    35  - GetErrorCode() - returns the error code, which is "component:reason"
    36  - GetStack() - returns just the callstack
    37  - WrapError(error) - wraps the provided error into the CallStackError
    38  
    39  Usage Instructions
    40  ------------------
    41  
    42  The new error handling framework should be used in place of all calls to
    43  ``fmt.Errorf()`` or ``Errors.new()``. Using this framework will provide error
    44  codes to check against as well as the option to generate a callstack that will be
    45  appended to the error message.
    46  
    47  Using the framework is simple and will only require an easy tweak to your code.
    48  
    49  First, you'll need to import **github.com/hyperledger/fabric/common/errors** into
    50  any file that uses this framework.
    51  
    52  Let's take the following as an example from core/chaincode/chaincode_support.go:
    53  
    54  .. code:: go
    55  
    56    err = fmt.Errorf("Error starting container: %s", err)
    57  
    58  For this error, we will simply call the constructor for Error and pass a
    59  component code, reason code, followed by the error message. At the end, we
    60  then call the ``WrapError()`` function, passing along the error itself.
    61  
    62  .. code:: go
    63  
    64    fmt.Errorf("Error starting container: %s", err)
    65  
    66  becomes
    67  
    68  .. code:: go
    69  
    70    errors.ErrorWithCallstack("CHA", "505", "Error starting container").WrapError(err)
    71  
    72  You could also just leave the message as is without any problems:
    73  
    74  .. code:: go
    75  
    76    errors.ErrorWithCallstack("CHA", "505", "Error starting container: %s", err)
    77  
    78  With this usage you will be able to format the error message from the previous
    79  error into the new error, but will lose the ability to print the callstack (if
    80  the wrapped error is a CallStackError).
    81  
    82  A second example to highlight a scenario that involves formatting directives for
    83  parameters other than errors, while still wrapping an error, is as follows:
    84  
    85  .. code:: go
    86  
    87    fmt.Errorf("failed to get deployment payload %s - %s", canName, err)
    88  
    89  becomes
    90  
    91  .. code:: go
    92  
    93    errors.ErrorWithCallstack("CHA", "506", "Failed to get deployment payload %s", canName).WrapError(err)
    94  
    95  Displaying error messages
    96  -------------------------
    97  
    98  Once the error has been created using the framework, displaying the error
    99  message is as simple as:
   100  
   101  .. code:: go
   102  
   103    logger.Errorf(err)
   104  
   105  or
   106  
   107  .. code:: go
   108  
   109    fmt.Println(err)
   110  
   111  or
   112  
   113  .. code:: go
   114  
   115    fmt.Printf("%s\n", err)
   116  
   117  An example from peer/common/common.go:
   118  
   119  .. code:: go
   120  
   121    errors.ErrorWithCallstack("PER", "404", "Error trying to connect to local peer").WrapError(err)
   122  
   123  would display the error message:
   124  
   125  .. code:: bash
   126  
   127    PER:404 - Error trying to connect to local peer
   128    Caused by: grpc: timed out when dialing
   129  
   130  .. note:: The callstacks have not been displayed for this example for the sake of
   131            brevity.
   132  
   133  General guidelines for error handling in Hyperledger Fabric
   134  -----------------------------------------------------------
   135  
   136  - If it is some sort of best effort thing you are doing, you should log the
   137    error and ignore it.
   138  - If you are servicing a user request, you should log the error and return it.
   139  - If the error comes from elsewhere, you have the choice to wrap the error
   140    or not. Typically, it's best to not wrap the error and simply return
   141    it as is. However, for certain cases where a utility function is called,
   142    wrapping the error with a new component and reason code can help an end user
   143    understand where the error is really occurring without inspecting the callstack.
   144  - A panic should be handled within the same layer by throwing an internal error
   145    code/start a recovery process and should not be allowed to propagate to other
   146    packages.
   147  
   148  .. Licensed under Creative Commons Attribution 4.0 International License
   149     https://creativecommons.org/licenses/by/4.0/
   150