Skip to content

Commit

Permalink
FIX BUG in error and WIP ADD tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Joubin Houshyar committed Mar 31, 2012
1 parent e13f256 commit 952b5c7
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 28 deletions.
13 changes: 5 additions & 8 deletions connection.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -173,12 +173,10 @@ func newConnHdl(spec *ConnectionSpec) (hdl *connHdl, err Error) {
switch { switch {
case e != nil: case e != nil:
err = NewErrorWithCause(SYSTEM_ERR, fmt.Sprintf("%s(): could not open connection", here), e) err = NewErrorWithCause(SYSTEM_ERR, fmt.Sprintf("%s(): could not open connection", here), e)
log.Println(err.Message()) return nil, withError(err)
return nil, err
case conn == nil: case conn == nil:
err = NewError(SYSTEM_ERR, fmt.Sprintf("%s(): net.Dial returned nil, nil (?)", here)) err = NewError(SYSTEM_ERR, fmt.Sprintf("%s(): net.Dial returned nil, nil (?)", here))
log.Println(err.Message()) return nil, withError(err)
return nil, err
default: default:
configureConn(conn, spec) configureConn(conn, spec)
hdl.spec = spec hdl.spec = spec
Expand Down Expand Up @@ -208,14 +206,14 @@ func (c *connHdl) onConnect() (e Error) {
if c.spec.password != DefaultRedisPassword { if c.spec.password != DefaultRedisPassword {
_, e = c.ServiceRequest(&AUTH, [][]byte{[]byte(c.spec.password)}) _, e = c.ServiceRequest(&AUTH, [][]byte{[]byte(c.spec.password)})
if e != nil { if e != nil {
log.Printf("Error on AUTH - e:%s", e.Message()) log.Printf("<ERROR> Authentication failed - %s", e.Message())
return return
} }
} }
if c.spec.db != DefaultRedisDB { if c.spec.db != DefaultRedisDB {
_, e = c.ServiceRequest(&SELECT, [][]byte{[]byte(fmt.Sprintf("%d", c.spec.db))}) _, e = c.ServiceRequest(&SELECT, [][]byte{[]byte(fmt.Sprintf("%d", c.spec.db))})
if e != nil { if e != nil {
log.Printf("Error on SELECT - e:%s", e.Message()) log.Printf("<ERROR> DB Select failed - %s", e.Message())
return return
} }
} }
Expand Down Expand Up @@ -253,11 +251,10 @@ type SyncConnection interface {
func NewSyncConnection(spec *ConnectionSpec) (c SyncConnection, err Error) { func NewSyncConnection(spec *ConnectionSpec) (c SyncConnection, err Error) {
connHdl, e := newConnHdl(spec) connHdl, e := newConnHdl(spec)
if e != nil { if e != nil {
log.Println("newConnHdl failed: " + e.Message())
return nil, e return nil, e
} }


connHdl.onConnect() e = connHdl.onConnect()
return connHdl, e return connHdl, e
} }


Expand Down
49 changes: 44 additions & 5 deletions error.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const (
REDIS_ERR REDIS_ERR
SYSTEM_ERR SYSTEM_ERR
) )

func (ec ErrorCategory) String() (s string) { func (ec ErrorCategory) String() (s string) {
switch ec { switch ec {
case SYSTEM_ERR: case SYSTEM_ERR:
Expand All @@ -53,21 +54,38 @@ func (ec ErrorCategory) String() (s string) {
} }
return return
} }

// Defines the interfce to get details of an Error. // Defines the interfce to get details of an Error.
// //
type Error interface { type Error interface {
// underlying error that caused this error - or nil
Cause() error Cause() error

// support std. Go Error interface
Error() string Error() string

// category of error -- never nil
Category() ErrorCategory Category() ErrorCategory

// the error message - if a Redis error these are exactly
// as provided by the server e.g. "ERR - invalid password"
// possibly "" if SYSTEM-ERR
Message() string Message() string

// conv to String
String() string String() string

// check if error is a Redis error e.g. "ERR - invalid password"
// a convenience method
IsRedisError() bool
} }
type redisError struct { type redisError struct {
msg string msg string
category ErrorCategory category ErrorCategory
cause error cause error
} }


func (e redisError) IsRedisError() bool { return e.category == REDIS_ERR}
func (e redisError) Cause() error { return e.cause } func (e redisError) Cause() error { return e.cause }
func (e redisError) Error() string { return e.String() } func (e redisError) Error() string { return e.String() }
func (e redisError) Category() ErrorCategory { return e.category } func (e redisError) Category() ErrorCategory { return e.category }
Expand Down Expand Up @@ -120,24 +138,45 @@ func NewErrorWithCause(cat ErrorCategory, msg string, cause error) Error {
return e return e
} }


// ----------------
// impl. utils // utility function emits log if _debug flag /debug() is true
// // Error is returned.
// a utility function for various components // usage:
// // foo, e := FooBar()
// if e != nil {
// return withError(e)
// }
func withError(e Error) Error { func withError(e Error) Error {
if debug() { if debug() {
log.Println(e) log.Println(e)
} }
return e return e
} }

// creates a new generic (Go) error
// and emits log if _debug flag /debug() is true
// Error is returned.
// usage:
// v := FooBar()
// if v != expected {
// return withNewError("value v is unexpected")
// }
func withNewError(m string) error { func withNewError(m string) error {
e := errors.New(m) e := errors.New(m)
if debug() { if debug() {
log.Println(e) log.Println(e)
} }
return e return e
} }

// creates a new redis.Error of category SYSTEM_ERR
// and emits log if _debug flag /debug() is true
// Error is returned.
// usage:
// _, e := SomeLibraryOrGoCall()
// if e != nil {
// return withNewError("value v is unexpected", e)
// }
func withOsError(m string, cause error) error { func withOsError(m string, cause error) error {
return withNewError(fmt.Sprintf("%s [cause: %s]", m, cause)) return withNewError(fmt.Sprintf("%s [cause: %s]", m, cause))
} }
18 changes: 13 additions & 5 deletions error_test.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -27,16 +27,16 @@ func testspec_et() tspec_et {


func commonErrorTest(t *testing.T, e Error, category ErrorCategory) { func commonErrorTest(t *testing.T, e Error, category ErrorCategory) {
if e.Error() == "" { if e.Error() == "" {
t.Error ("BUG: nil results for e.Error()") t.Error("BUG: nil results for e.Error()")
} }
if e.Message() == "" { if e.Message() == "" {
t.Error ("BUG: nil results for e.Message()") t.Error("BUG: nil results for e.Message()")
} }
if e.String() == "" { if e.String() == "" {
t.Error ("BUG: nil results for e.String()") t.Error("BUG: nil results for e.String()")
} }
if e.Category() != category { if e.Category() != category {
t.Errorf ("BUG: category not set correctly (exp:%s | got:%s)", category, e.Category()) t.Errorf("BUG: category not set correctly (exp:%s | got:%s)", category, e.Category())
} }
} }


Expand All @@ -59,20 +59,28 @@ func TestNewRedisError(t *testing.T) {
spec := testspec_et() spec := testspec_et()
e := NewRedisError(spec.msg) e := NewRedisError(spec.msg)
commonErrorTest(t, e, REDIS_ERR) commonErrorTest(t, e, REDIS_ERR)

if !e.IsRedisError() {
t.Error("BUG: IsRedisError")
}
} }


func TestNewSystemError(t *testing.T) { func TestNewSystemError(t *testing.T) {


spec := testspec_et() spec := testspec_et()
e := NewSystemError(spec.msg) e := NewSystemError(spec.msg)
commonErrorTest(t, e, SYSTEM_ERR) commonErrorTest(t, e, SYSTEM_ERR)

if e.IsRedisError() {
t.Error("BUG: IsRedisError")
}
} }


func TestNewErrorWithCause(t *testing.T) { func TestNewErrorWithCause(t *testing.T) {


spec := testspec_et() spec := testspec_et()


var cause simpleError; var cause simpleError
e := NewErrorWithCause(spec.category, spec.msg, cause) e := NewErrorWithCause(spec.category, spec.msg, cause)


commonErrorTest(t, e, spec.category) commonErrorTest(t, e, spec.category)
Expand Down
10 changes: 6 additions & 4 deletions redis.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ package redis


import ( import (
"flag" "flag"
// "runtime"; "runtime";
) )


// Common interface supported by all clients // Common interface supported by all clients
Expand Down Expand Up @@ -518,13 +518,15 @@ type AsyncClient interface {
// for this package are all prefixed by "redis:" to prevent possible name collisions. // for this package are all prefixed by "redis:" to prevent possible name collisions.
// //
func init() { func init() {
// runtime.GOMAXPROCS(2); runtime.GOMAXPROCS(2);
// flag.Parse(); flag.Parse();
} }


// redis:d // redis:d
// //
// global debug flag for redis package components. // global debug flag for redis package components.
// //
var _debug *bool = flag.Bool("redis:d", false, "debug flag for go-redis") // TEMP: should default to false var _debug *bool = flag.Bool("redis:d", false, "debug flag for go-redis") // TEMP: should default to false
func debug() bool { return *_debug } func debug() bool {
return *_debug
}
7 changes: 3 additions & 4 deletions synchclient.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -51,12 +51,11 @@ func NewSynchClient() (c Client, err Error) {
// //
func NewSynchClientWithSpec(spec *ConnectionSpec) (c Client, err Error) { func NewSynchClientWithSpec(spec *ConnectionSpec) (c Client, err Error) {
_c := new(syncClient) _c := new(syncClient)
conn, err := NewSyncConnection(spec) _c.conn, err = NewSyncConnection(spec)
if err != nil { if err != nil {
log.Println("NewSyncConnection() raised error: ", err.Message()) return nil, withError (err)
return nil, err
} }
_c.conn = conn // _c.conn = conn
return _c, nil return _c, nil
} }


Expand Down
19 changes: 17 additions & 2 deletions synchclient_test.go
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ type tspec_sct struct {
connspec *ConnectionSpec connspec *ConnectionSpec
} }


// default values for test
//
func testspec_sct() tspec_sct { func testspec_sct() tspec_sct {
var spec tspec_sct var spec tspec_sct


Expand All @@ -25,16 +27,29 @@ func testspec_sct() tspec_sct {
return spec return spec
} }


func TestClientConnectWithBadSpec(t *testing.T) {
spec := testspec_sct()
spec.connspec.Password("bad-password")
c, err := NewSynchClientWithSpec(spec.connspec)
if err == nil {
t.Error("BUG: Expected a RedisError")
}
if c != nil {
t.Error("BUG: client reference expected to be nil")
}
}

func TestClientConnectWithSpec(t *testing.T) { func TestClientConnectWithSpec(t *testing.T) {
spec := testspec_sct() spec := testspec_sct()


c, err := NewSynchClientWithSpec(spec.connspec) c, err := NewSynchClientWithSpec(spec.connspec)
if err != nil { if err != nil {
t.Error("failed to create client with spec. Error: %s", err.Message()) t.Error("failed to create client with spec. Error: ", err.Message())
} else if c == nil { } else if c == nil {
t.Error("failed to create client with spec. Error: %s") t.Error("BUG: client is nil")
} }
} }

func TestEnd_sct(t *testing.T) { func TestEnd_sct(t *testing.T) {
log.Println("synchclient test") log.Println("synchclient test")
} }

0 comments on commit 952b5c7

Please sign in to comment.