THRIFT-2337 Golang does not report TIMED_OUT exceptions
authorJens Geyer <jensg@apache.org>
Thu, 30 Jan 2014 19:57:08 +0000 (20:57 +0100)
committerJens Geyer <jensg@apache.org>
Thu, 30 Jan 2014 19:57:08 +0000 (20:57 +0100)
Patch: Chris Bannister

lib/go/thrift/transport_exception.go
lib/go/thrift/transport_exception_test.go [new file with mode: 0644]

index dbab4d9..9505b44 100644 (file)
 package thrift
 
 import (
+       "errors"
        "io"
 )
 
+type timeoutable interface {
+       Timeout() bool
+}
+
 // Thrift Transport exception
 type TTransportException interface {
        TException
        TypeId() int
+       Err() error
 }
 
 const (
@@ -38,8 +44,8 @@ const (
 )
 
 type tTransportException struct {
-       typeId  int
-       message string
+       typeId int
+       err    error
 }
 
 func (p *tTransportException) TypeId() int {
@@ -47,22 +53,38 @@ func (p *tTransportException) TypeId() int {
 }
 
 func (p *tTransportException) Error() string {
-       return p.message
+       return p.err.Error()
 }
 
-func NewTTransportException(t int, m string) TTransportException {
-       return &tTransportException{typeId: t, message: m}
+func (p *tTransportException) Err() error {
+       return p.err
+}
+
+func NewTTransportException(t int, e string) TTransportException {
+       return &tTransportException{typeId: t, err: errors.New(e)}
 }
 
 func NewTTransportExceptionFromError(e error) TTransportException {
        if e == nil {
                return nil
        }
+
        if t, ok := e.(TTransportException); ok {
                return t
        }
+
+       switch v := e.(type) {
+       case TTransportException:
+               return v
+       case timeoutable:
+               if v.Timeout() {
+                       return &tTransportException{typeId: TIMED_OUT, err: e}
+               }
+       }
+
        if e == io.EOF {
-               return NewTTransportException(END_OF_FILE, e.Error())
+               return &tTransportException{typeId: END_OF_FILE, err: e}
        }
-       return NewTTransportException(UNKNOWN_TRANSPORT_EXCEPTION, e.Error())
+
+       return &tTransportException{typeId: UNKNOWN_TRANSPORT_EXCEPTION, err: e}
 }
diff --git a/lib/go/thrift/transport_exception_test.go b/lib/go/thrift/transport_exception_test.go
new file mode 100644 (file)
index 0000000..55b0a77
--- /dev/null
@@ -0,0 +1,41 @@
+package thrift
+
+import (
+       "fmt"
+       "io"
+
+       "testing"
+)
+
+type timeout struct{ timedout bool }
+
+func (t *timeout) Timeout() bool {
+       return t.timedout
+}
+
+func (t *timeout) Error() string {
+       return fmt.Sprintf("Timeout: %v", t.timedout)
+}
+
+func TestTExceptionTimeout(t *testing.T) {
+       timeout := &timeout{true}
+       exception := NewTTransportExceptionFromError(timeout)
+       if timeout.Error() != exception.Error() {
+               t.Fatalf("Error did not match: expected %q, got %q", timeout.Error(), exception.Error())
+       }
+
+       if exception.TypeId() != TIMED_OUT {
+               t.Fatalf("TypeId was not TIMED_OUT: expected %v, got %v", TIMED_OUT, exception.TypeId())
+       }
+}
+
+func TestTExceptionEOF(t *testing.T) {
+       exception := NewTTransportExceptionFromError(io.EOF)
+       if io.EOF.Error() != exception.Error() {
+               t.Fatalf("Error did not match: expected %q, got %q", io.EOF.Error(), exception.Error())
+       }
+
+       if exception.TypeId() != END_OF_FILE {
+               t.Fatalf("TypeId was not END_OF_FILE: expected %v, got %v", END_OF_FILE, exception.TypeId())
+       }
+}