From d46c7bcaf9268a191f0156d36abf394df5374795 Mon Sep 17 00:00:00 2001 From: zelig Date: Wed, 25 Feb 2015 19:21:59 +0700 Subject: [PATCH] errs pkg for error code based errors --- errs/errors.go | 91 +++++++++++++++++++++++++++++++++++++++++++++ errs/errors_test.go | 46 +++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 errs/errors.go create mode 100644 errs/errors_test.go diff --git a/errs/errors.go b/errs/errors.go new file mode 100644 index 0000000000..f1b0ebdbbb --- /dev/null +++ b/errs/errors.go @@ -0,0 +1,91 @@ +package errs + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/logger" +) + +/* +Errors implements an error handler providing standardised errors for a package. +Fields: + + Errors: + a map from error codes to description + + Package: + name of the package/component + + Level: + a function mapping error code to logger.LogLevel (severity) + if not given, errors default to logger.InfoLevel +*/ +type Errors struct { + Errors map[int]string + Package string + Level func(code int) logger.LogLevel +} + +/* +Error implements the standard go error interface. + + errors.New(code, format, params ...interface{}) + +Prints as: + + [package] description: details + +where details is fmt.Sprintf(self.format, self.params...) +*/ +type Error struct { + Code int + Name string + Package string + level logger.LogLevel + message string + format string + params []interface{} +} + +func (self *Errors) New(code int, format string, params ...interface{}) *Error { + name, ok := self.Errors[code] + if !ok { + panic("invalid error code") + } + level := logger.InfoLevel + if self.Level != nil { + level = self.Level(code) + } + return &Error{ + Code: code, + Name: name, + Package: self.Package, + level: level, + format: format, + params: params, + } +} + +func (self Error) Error() (message string) { + if len(message) == 0 { + self.message = fmt.Sprintf("[%s] %s", self.Package, self.Name) + if self.format != "" { + self.message += ": " + fmt.Sprintf(self.format, self.params...) + } + } + return self.message +} + +func (self Error) Log(log *logger.Logger) { + log.Sendln(self.level, self) +} + +/* +err.Fatal() is true if err's severity level is 0 or 1 (logger.ErrorLevel or logger.Silence) +*/ +func (self *Error) Fatal() (fatal bool) { + if self.level < logger.WarnLevel { + fatal = true + } + return +} diff --git a/errs/errors_test.go b/errs/errors_test.go new file mode 100644 index 0000000000..09f70eef53 --- /dev/null +++ b/errs/errors_test.go @@ -0,0 +1,46 @@ +package errs + +import ( + "fmt" + "testing" + + "github.com/ethereum/go-ethereum/logger" +) + +func testErrors() *Errors { + return &Errors{ + Package: "TEST", + Errors: map[int]string{ + 0: "zero", + 1: "one", + }, + Level: func(i int) (l logger.LogLevel) { + if i == 0 { + l = logger.ErrorLevel + } else { + l = logger.WarnLevel + } + return + }, + } +} + +func TestErrorMessage(t *testing.T) { + err := testErrors().New(0, "zero detail %v", "available") + message := fmt.Sprintf("%v", err) + exp := "[TEST] zero: zero detail available" + if message != exp { + t.Errorf("error message incorrect. expected %v, got %v", exp, message) + } +} + +func TestErrorSeverity(t *testing.T) { + err0 := testErrors().New(0, "zero detail") + if !err0.Fatal() { + t.Errorf("error should be fatal") + } + err1 := testErrors().New(1, "one detail") + if err1.Fatal() { + t.Errorf("error should not be fatal") + } +}