Skip to content

Commit

Permalink
Merge "Simplify error handling framework messages"
Browse files Browse the repository at this point in the history
  • Loading branch information
Srinivasan Muralidharan authored and Gerrit Code Review committed Jan 19, 2017
2 parents add2776 + 6ef96a1 commit 18b4089
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 18b4089

Please sign in to comment.