Skip to content

Commit

Permalink
[FAB-3548] Define error and component codes
Browse files Browse the repository at this point in the history
    This changeset defines the starter set of error and component
    codes as constants to use in error reporting.

Change-Id: I8cf02f6fa76d2bc858e5c287da6d7cf9cc1c5fc1
Signed-off-by: Binh Q. Nguyen <binhn@us.ibm.com>
  • Loading branch information
binhn committed May 3, 2017
1 parent 2f55f4a commit 7bee71e
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 26 deletions.
104 changes: 104 additions & 0 deletions common/errors/codes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/*
Copyright Digital Asset Holdings, LLC 2016 All Rights Reserved.
Copyright IBM Corp. 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package errors

// A set of constants for error reason codes, which is based on HTTP codes
// http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
const (
// Invalid inputs on API calls
BadRequest = "400"

// Forbidden due to access control issues
Forbidden = "403"

// Not Found (eg chaincode not found)
NotFound = "404"

// Request timeout (chaincode or ledger)
Timeout = "408"

// Example, duplicate transactions or replay attacks
Conflict = "409"

// Request for resource is not available. Example, a chaincode has
// been upgraded and the request uses an old version
Gone = "410"

// Payload of the request exceeds allowed size
PayloadTooLarge = "413"

// Example, marshal/unmarshalling protobuf error
UnprocessableEntity = "422"

// Protocol version is no longer supported
UpgradeRequired = "426"

// Internal server errors that are not classified below
Internal = "500"

// Requested chaincode function has not been implemented
NotImplemented = "501"

// Requested chaincode is not available
Unavailable = "503"

// File IO errors
FileIO = "520"

// Network IO errors
NetworkIO = "521"
)

// A set of constants for component codes
const (
// BCCSP is fabic/BCCSP
BCCSP = "CSP"

// Common is fabric/common
Common = "CMN"

// Core is fabric/core
Core = "COR"

// Event is fabric/events component
Event = "EVT"

// Gossip is fabric/gossip
Gossip = "GSP"

// Ledger is fabric/core/ledger
Ledger = "LGR"

// Peer is fabric/peer
Peer = "PER"

// Orderer is fabric/orderer
Orderer = "ORD"

// MSP is fabric/msp
MSP = "MSP"

// ChaincodeSupport is fabric/core/chaincode
ChaincodeSupport = "CCS"

// DeliveryService is fabric/core/deliverservice
DeliveryService = "CDS"

// SystemChaincode is fabric/core/scc (system chaincode)
SystemChaincode = "SCC"
)
18 changes: 9 additions & 9 deletions common/errors/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ func TestError(t *testing.T) {
var tc []testCase

tc = append(tc,
testCase{"UnknownErrorWithCallstack", []string{"UNK", "404", "An unknown error occurred."}, nil, nil, nil, []bool{true}},
testCase{"UnknownError", []string{"UNK", "404", "An unknown error occurred."}, nil, nil, nil, []bool{false}},
testCase{"UnknownErrorWithCallstackAndArg", []string{"UNK", "405", "An error occurred: %s"}, []string{"arg1"}, nil, nil, []bool{true}},
testCase{"UnknownErrorWithArg", []string{"UNK", "405", "An error occurred: %s"}, []string{"arg1"}, nil, nil, []bool{false}},
testCase{"CallStackErrorWrappedCallstackError", []string{"CHA", "404", "An unknown error occurred."}, nil, []string{"UNK", "404", "An unknown error occurred."}, nil, []bool{true, true}},
testCase{"ErrorWrappedError", []string{"CHA", "404", "An unknown error occurred."}, nil, []string{"UNK", "404", "An unknown error occurred."}, nil, []bool{false, false}},
testCase{"CallStackErrorWrappedError", []string{"CHA", "404", "An unknown error occurred."}, nil, []string{"UNK", "404", "An unknown error occurred."}, nil, []bool{true, false}},
testCase{"ErrorWrappedCallStackError", []string{"CHA", "404", "An unknown error occurred."}, nil, []string{"UNK", "404", "An unknown error occurred."}, nil, []bool{false, true}},
testCase{"ErrorWrappedStandardError", []string{"CHA", "404", "An unknown error occurred."}, nil, []string{"grpc timed out: %s"}, []string{"failed to connect to server"}, []bool{false, true}},
testCase{"UnknownErrorWithCallstack", []string{Core, NotFound, "An unknown error occurred."}, nil, nil, nil, []bool{true}},
testCase{"UnknownError", []string{MSP, Forbidden, "An unknown error occurred."}, nil, nil, nil, []bool{false}},
testCase{"UnknownErrorWithCallstackAndArg", []string{Ledger, Conflict, "An error occurred: %s"}, []string{"arg1"}, nil, nil, []bool{true}},
testCase{"UnknownErrorWithArg", []string{SystemChaincode, Internal, "An error occurred: %s"}, []string{"arg1"}, nil, nil, []bool{false}},
testCase{"CallStackErrorWrappedCallstackError", []string{BCCSP, NotImplemented, "An unknown error occurred."}, nil, []string{Peer, UpgradeRequired, "An unknown error occurred."}, nil, []bool{true, true}},
testCase{"ErrorWrappedError", []string{Common, Unavailable, "An unknown error occurred."}, nil, []string{SystemChaincode, Gone, "An unknown error occurred."}, nil, []bool{false, false}},
testCase{"CallStackErrorWrappedError", []string{Event, Timeout, "An unknown error occurred."}, nil, []string{Orderer, NetworkIO, "An unknown error occurred."}, nil, []bool{true, false}},
testCase{"ErrorWrappedCallStackError", []string{Orderer, UnprocessableEntity, "An unknown error occurred."}, nil, []string{"UNK", "404", "An unknown error occurred."}, nil, []bool{false, true}},
testCase{"ErrorWrappedStandardError", []string{DeliveryService, Unavailable, "An unknown error occurred."}, nil, []string{"grpc timed out: %s"}, []string{"failed to connect to server"}, []bool{false, true}},
)

assert := assert.New(t)
Expand Down
25 changes: 8 additions & 17 deletions docs/source/error-handling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,14 @@ 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.

.. note:: Make sure to use a consistent component name across code in related
files/packages.
Examples of component codes (with their full component name in parentheses)
are: CSP (bccsp), CMN (common), COR (core), CCS (core/chaincode), CDS
(core/deliverservice), SCC (core/scc), EVT (events), GSP (gossip), LGR
(ledger), PER (peer), ORD (orderer)

We may, in the future, add constants to allow searching for currently defined
components for those using an editor with code completion capabilities.

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.
characters are not allowed. A set of reason codes is defined in
common/error/codes.go
- Error code - the component code and reason code separated by a colon,
e.g. PER:404
e.g. MSP:404
- 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.
Expand All @@ -39,9 +30,9 @@ The CallStackError interface exposes the following functions:

- Error() - returns the error message with callstack appended
- Message() - returns the error message (without callstack appended)
- GetComponentCode()
- GetReasonCode()
- GetErrorCode()
- GetComponentCode() - returns the 3-character component code
- GetReasonCode() - returns the 3-digit reason code
- GetErrorCode() - returns the error code, which is "component:reason"
- GetStack() - returns just the callstack
- WrapError(error) - wraps the provided error into the CallStackError

Expand Down

0 comments on commit 7bee71e

Please sign in to comment.