Skip to content

Commit

Permalink
Simplify error handling framework messages
Browse files Browse the repository at this point in the history
This changeset removes the error handling framework's use of an
error message map and any code that was in place to add future
language translations. This simplification will allow easier adoption
of internationalization packages whenever that is deemed a priority.

https://jira.hyperledger.org/browse/FAB-1571

Change-Id: I0ae562ebdc10d43c99d5099039671769199af95e
Signed-off-by: Will Lahti <wtlahti@us.ibm.com>
  • Loading branch information
wlahti committed Jan 18, 2017
1 parent aaa998e commit 6ef96a1
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 150 deletions.
57 changes: 21 additions & 36 deletions core/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package errors

import (
"bytes"
"encoding/json"
"fmt"
"runtime"

Expand Down Expand Up @@ -46,24 +45,6 @@ type CallStackError interface {
GetComponentCode() ComponentCode
GetReasonCode() ReasonCode
Message() string
MessageIn(string) string
}

type errormap map[string]map[string]map[string]string

var emap errormap

const language string = "en"

func init() {
initErrors()
}

func initErrors() {
e := json.Unmarshal([]byte(errorMapping), &emap)
if e != nil {
panic(e)
}
}

type callstack []uintptr
Expand All @@ -77,6 +58,7 @@ type hlError struct {
stack callstack
componentcode ComponentCode
reasoncode ReasonCode
message string
args []interface{}
stackGetter func(callstack) string
}
Expand All @@ -90,8 +72,9 @@ func newHLError(debug bool) *hlError {
}

func setupHLError(e *hlError, debug bool) {
e.componentcode = Utility
e.reasoncode = UtilityUnknownError
e.componentcode = "Utility"
e.reasoncode = "UnknownError"
e.message = "An unknown error has occurred."
if !debug {
e.stackGetter = noopGetStack
return
Expand All @@ -113,12 +96,12 @@ func (h *hlError) GetStack() string {
return h.stackGetter(h.stack)
}

// GetComponentCode returns the Return code
// GetComponentCode returns the component name
func (h *hlError) GetComponentCode() ComponentCode {
return h.componentcode
}

// GetReasonCode returns the Reason code
// GetReasonCode returns the reason code - i.e. why the error occurred
func (h *hlError) GetReasonCode() ReasonCode {
return h.reasoncode
}
Expand All @@ -130,43 +113,45 @@ func (h *hlError) GetErrorCode() string {

// Message returns the corresponding error message for this error in default
// language.
// TODO - figure out the best way to read in system language instead of using
// hard-coded default language
func (h *hlError) Message() string {
// initialize logging level for errors from core.yaml. it can also be set
// for code running on the peer dynamically via CLI using
// "peer logging setlevel error <log-level>"
errorLogLevelString, _ := flogging.GetModuleLevel("error")

message := fmt.Sprintf(h.message, h.args...)
if errorLogLevelString == logging.DEBUG.String() {
messageWithCallStack := fmt.Sprintf(emap[fmt.Sprintf("%s", h.componentcode)][fmt.Sprintf("%s", h.reasoncode)][language], h.args...) + "\n" + h.GetStack()
return messageWithCallStack
message = appendCallStack(message, h.GetStack())
}
return fmt.Sprintf(emap[fmt.Sprintf("%s", h.componentcode)][fmt.Sprintf("%s", h.reasoncode)][language], h.args...)

return message
}

// MessageIn returns the corresponding error message for this error in 'language'
func (h *hlError) MessageIn(language string) string {
return fmt.Sprintf(emap[fmt.Sprintf("%s", h.componentcode)][fmt.Sprintf("%s", h.reasoncode)][language], h.args...)
func appendCallStack(message string, callstack string) string {
messageWithCallStack := message + "\n" + callstack

return messageWithCallStack
}

// Error creates a CallStackError using a specific Component Code and
// Reason Code (no callstack is recorded)
func Error(componentcode ComponentCode, reasoncode ReasonCode, args ...interface{}) CallStackError {
return newCustomError(componentcode, reasoncode, false, args...)
func Error(componentcode ComponentCode, reasoncode ReasonCode, message string, args ...interface{}) CallStackError {
return newCustomError(componentcode, reasoncode, message, false, args...)
}

// ErrorWithCallstack creates a CallStackError using a specific Component Code and
// Reason Code and fills its callstack
func ErrorWithCallstack(componentcode ComponentCode, reasoncode ReasonCode, args ...interface{}) CallStackError {
return newCustomError(componentcode, reasoncode, true, args...)
func ErrorWithCallstack(componentcode ComponentCode, reasoncode ReasonCode, message string, args ...interface{}) CallStackError {
return newCustomError(componentcode, reasoncode, message, true, args...)
}

func newCustomError(componentcode ComponentCode, reasoncode ReasonCode, generateStack bool, args ...interface{}) CallStackError {
func newCustomError(componentcode ComponentCode, reasoncode ReasonCode, message string, generateStack bool, args ...interface{}) CallStackError {
e := &hlError{}
setupHLError(e, generateStack)
e.componentcode = componentcode
e.reasoncode = reasoncode
e.args = args
e.message = message
return e
}

Expand Down
86 changes: 0 additions & 86 deletions core/errors/errors_json.go

This file was deleted.

40 changes: 17 additions & 23 deletions core/errors/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import (
)

func TestError(t *testing.T) {
e := Error(Utility, UtilityUnknownError)
e := Error("Utility", "ErrorWithArg", "An unknown error occurred.")
s := e.GetStack()
if s != "" {
t.Fatalf("No error stack should have been recorded.")
Expand All @@ -34,15 +34,15 @@ func TestError(t *testing.T) {

// TestErrorWithArg tests creating an error with a message argument
func TestErrorWithArg(t *testing.T) {
e := Error(Utility, UtilityErrorWithArg, "arg1")
e := Error("Utility", "ErrorWithArg", "An error occurred: %s", "arg1")
s := e.GetStack()
if s != "" {
t.Fatalf("No error stack should have been recorded.")
}
}

func TestErrorWithCallstack(t *testing.T) {
e := ErrorWithCallstack(Utility, UtilityUnknownError)
e := ErrorWithCallstack("Utility", "UnknownError", "An unknown error occurred.")
s := e.GetStack()
if s == "" {
t.Fatalf("No error stack was recorded.")
Expand All @@ -52,7 +52,7 @@ func TestErrorWithCallstack(t *testing.T) {
// TestErrorWithCallstackAndArg tests creating an error with a callstack and
// message argument
func TestErrorWithCallstackAndArg(t *testing.T) {
e := ErrorWithCallstack(Utility, UtilityErrorWithArg, "arg1")
e := ErrorWithCallstack("Utility", "ErrorWithArg", "An error occurred: %s", "arg1")
s := e.GetStack()
if s == "" {
t.Fatalf("No error stack was recorded.")
Expand All @@ -67,7 +67,7 @@ func TestErrorWithCallstackMessage(t *testing.T) {
// to the error message
flogging.SetModuleLevel("error", "debug")

e := ErrorWithCallstack(Utility, UtilityUnknownError)
e := ErrorWithCallstack("Utility", "ErrorWithArg", "An unknown error occurred.")
s := e.GetStack()
if s == "" {
t.Fatalf("No error stack was recorded.")
Expand All @@ -85,73 +85,67 @@ func ExampleError() {
// not be appended to the error message
flogging.SetModuleLevel("error", "warning")

err := ErrorWithCallstack(Utility, UtilityUnknownError)
err := ErrorWithCallstack("Utility", "UnknownError", "An unknown error occurred.")

if err != nil {
fmt.Printf("%s\n", err.Error())
fmt.Printf("%s\n", err.GetErrorCode())
fmt.Printf("%s\n", err.GetComponentCode())
fmt.Printf("%s\n", err.GetReasonCode())
fmt.Printf("%s\n", err.Message())
fmt.Printf("%s\n", err.MessageIn("en"))
// Output:
// An unknown error occurred.
// Utility-UtilityUnknownError
// Utility-UnknownError
// Utility
// UtilityUnknownError
// An unknown error occurred.
// UnknownError
// An unknown error occurred.
}
}

// ExampleErrorWithArg tests the output for a sample error with a message
// argument
func ExampleUtilityErrorWithArg() {
func Example_utilityErrorWithArg() {
// when the 'error' module is set to anything but debug, the callstack will
// not be appended to the error message
flogging.SetModuleLevel("error", "warning")

err := ErrorWithCallstack(Utility, UtilityErrorWithArg, "arg1")
err := ErrorWithCallstack("Utility", "ErrorWithArg", "An error occurred: %s", "arg1")

if err != nil {
fmt.Printf("%s\n", err.Error())
fmt.Printf("%s\n", err.GetErrorCode())
fmt.Printf("%s\n", err.GetComponentCode())
fmt.Printf("%s\n", err.GetReasonCode())
fmt.Printf("%s\n", err.Message())
fmt.Printf("%s\n", err.MessageIn("en"))
// Output:
// An error occurred: arg1
// Utility-UtilityErrorWithArg
// Utility-ErrorWithArg
// Utility
// UtilityErrorWithArg
// An error occurred: arg1
// ErrorWithArg
// An error occurred: arg1
}
}

// ExampleLoggingInvalidLogLevel tests the output for a logging error where
// Example_loggingInvalidLevel tests the output for a logging error where
// and an invalid log level has been provided
func ExampleLoggingInvalidLogLevel() {
func Example_loggingInvalidLevel() {
// when the 'error' module is set to anything but debug, the callstack will
// not be appended to the error message
flogging.SetModuleLevel("error", "warning")

err := ErrorWithCallstack(Logging, LoggingInvalidLogLevel, "invalid")
err := ErrorWithCallstack("Logging", "InvalidLevel", "Invalid log level provided - %s", "invalid")

if err != nil {
fmt.Printf("%s\n", err.Error())
fmt.Printf("%s\n", err.GetErrorCode())
fmt.Printf("%s\n", err.GetComponentCode())
fmt.Printf("%s\n", err.GetReasonCode())
fmt.Printf("%s\n", err.Message())
fmt.Printf("%s\n", err.MessageIn("en"))
// Output:
// Invalid log level provided - invalid
// Logging-LoggingInvalidLogLevel
// Logging-InvalidLevel
// Logging
// LoggingInvalidLogLevel
// Invalid log level provided - invalid
// InvalidLevel
// Invalid log level provided - invalid
}
}
6 changes: 3 additions & 3 deletions peer/clilogging/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,19 @@ func checkLoggingCmdParams(cmd *cobra.Command, args []string) error {

// check that at least one parameter is passed in
if len(args) == 0 {
err = errors.ErrorWithCallstack(errors.Logging, errors.LoggingNoParameters)
err = errors.ErrorWithCallstack("Logging", "NoParameters", "No parameters provided.")
return err
}

if cmd.Name() == "setlevel" {
// check that log level parameter is provided
if len(args) == 1 {
err = errors.ErrorWithCallstack(errors.Logging, errors.LoggingNoLogLevelParameter)
err = errors.ErrorWithCallstack("Logging", "NoLevelParameter", "No log level provided.")
} else {
// check that log level is valid. if not, err is set
_, err = logging.LogLevel(args[1])
if err != nil {
err = errors.ErrorWithCallstack(errors.Logging, errors.LoggingInvalidLogLevel, args[1])
err = errors.ErrorWithCallstack("Logging", "InvalidLevel", "Invalid log level provided - %s", args[1])
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions peer/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func InitCrypto(mspMgrConfigDir string) error {
func GetEndorserClient() (pb.EndorserClient, error) {
clientConn, err := peer.NewPeerClientConnection()
if err != nil {
err = errors.ErrorWithCallstack(errors.Peer, errors.PeerConnectionError, err.Error())
err = errors.ErrorWithCallstack("Peer", "ConnectionError", "Error trying to connect to local peer: %s", err.Error())
return nil, err
}
endorserClient := pb.NewEndorserClient(clientConn)
Expand All @@ -90,7 +90,7 @@ func GetEndorserClient() (pb.EndorserClient, error) {
func GetAdminClient() (pb.AdminClient, error) {
clientConn, err := peer.NewPeerClientConnection()
if err != nil {
err = errors.ErrorWithCallstack(errors.Peer, errors.PeerConnectionError, err.Error())
err = errors.ErrorWithCallstack("Peer", "ConnectionError", "Error trying to connect to local peer: %s", err.Error())
return nil, err
}
adminClient := pb.NewAdminClient(clientConn)
Expand Down

0 comments on commit 6ef96a1

Please sign in to comment.