Merge pull request #57 from fangyincheng/master
Fix:java exception
diff --git a/hessian.go b/hessian.go
index ff39d92..24aa2e1 100644
--- a/hessian.go
+++ b/hessian.go
@@ -17,6 +17,7 @@
import (
"bufio"
"encoding/binary"
+ "reflect"
"time"
)
@@ -26,11 +27,12 @@
// enum part
const (
- PackageError = PackageType(0x01)
- PackageRequest = PackageType(0x02)
- PackageResponse = PackageType(0x04)
- PackageHeartbeat = PackageType(0x08)
- PackageRequest_TwoWay = PackageType(0x10)
+ PackageError = PackageType(0x01)
+ PackageRequest = PackageType(0x02)
+ PackageResponse = PackageType(0x04)
+ PackageHeartbeat = PackageType(0x08)
+ PackageRequest_TwoWay = PackageType(0x10)
+ PackageResponse_Exception = PackageType(0x20)
)
// PackageType ...
@@ -131,18 +133,8 @@
} else {
header.Type |= PackageResponse
header.ResponseStatus = buf[3]
-
- // Header{status}
- if buf[3] != Response_OK {
- err = ErrJavaException
- header.Type |= PackageError
- bufSize := h.reader.Buffered()
- if bufSize > 1 {
- expBuf, expErr := h.reader.Peek(bufSize)
- if expErr == nil {
- err = perrors.Errorf("java exception:%s", string(expBuf[1:bufSize-1]))
- }
- }
+ if header.ResponseStatus != Response_OK {
+ header.Type |= PackageResponse_Exception
}
}
@@ -158,6 +150,10 @@
h.pkgType = header.Type
h.bodyLen = header.BodyLen
+ if h.reader.Buffered() < h.bodyLen {
+ return ErrBodyNotEnough
+ }
+
return perrors.WithStack(err)
}
@@ -166,7 +162,7 @@
func (h *HessianCodec) ReadBody(rspObj interface{}) error {
if h.reader.Buffered() < h.bodyLen {
- return ErrHeaderNotEnough
+ return ErrBodyNotEnough
}
buf, err := h.reader.Peek(h.bodyLen)
if err != nil {
@@ -177,23 +173,29 @@
return perrors.WithStack(err)
}
- switch h.pkgType & 0x0f {
- case PackageRequest | PackageHeartbeat, PackageResponse | PackageHeartbeat:
+ switch h.pkgType & 0x2f {
+ case PackageResponse | PackageHeartbeat | PackageResponse_Exception, PackageResponse | PackageResponse_Exception:
+ rsp, ok := rspObj.(*Response)
+ if !ok {
+ return perrors.Errorf("@rspObj is not *Response, it is %s", reflect.TypeOf(rspObj).String())
+ }
+ rsp.Exception = ErrJavaException
+ if h.bodyLen > 1 {
+ rsp.Exception = perrors.Errorf("java exception:%s", string(buf[1:h.bodyLen-1]))
+ }
return nil
+ case PackageRequest | PackageHeartbeat, PackageResponse | PackageHeartbeat:
case PackageRequest:
if rspObj != nil {
if err = unpackRequestBody(buf, rspObj); err != nil {
return perrors.WithStack(err)
}
}
-
- return nil
-
case PackageResponse:
if rspObj != nil {
rsp, ok := rspObj.(*Response)
if !ok {
- break
+ rsp = &Response{RspObj: rspObj}
}
if err = unpackResponseBody(buf, rsp); err != nil {
return perrors.WithStack(err)
diff --git a/hessian_test.go b/hessian_test.go
index e9d62c0..45b4768 100644
--- a/hessian_test.go
+++ b/hessian_test.go
@@ -62,13 +62,8 @@
h := &DubboHeader{}
err = codecR.ReadHeader(h)
- if responseStatus == Response_OK {
- assert.Nil(t, err)
- } else {
- t.Log(err)
- assert.NotNil(t, err)
- return
- }
+ assert.Nil(t, err)
+
assert.Equal(t, byte(2), h.SerialID)
assert.Equal(t, packageType, h.Type&(PackageRequest|PackageResponse|PackageHeartbeat))
assert.Equal(t, int64(1), h.ID)
@@ -83,6 +78,11 @@
return
}
+ if h.ResponseStatus != Zero && h.ResponseStatus != Response_OK {
+ assert.Equal(t, "java exception:"+body.(string), decodedResponse.Exception.Error())
+ return
+ }
+
in, _ := EnsureInterface(UnpackPtrValue(EnsurePackValue(body)), nil)
out, _ := EnsureInterface(UnpackPtrValue(EnsurePackValue(decodedResponse.RspObj)), nil)
assert.Equal(t, in, out)
diff --git a/response.go b/response.go
index 2eb4b20..63a2307 100644
--- a/response.go
+++ b/response.go
@@ -62,43 +62,45 @@
encoder := NewEncoder()
encoder.Append(byteArray[:HEADER_LENGTH])
- if hb {
- encoder.Encode(nil)
- } else if header.ResponseStatus == Response_OK {
- // com.alibaba.dubbo.rpc.protocol.dubbo.DubboCodec.DubboCodec.java
- // v2.7.1 line191 encodeRequestData
-
- atta := isSupportResponseAttachment(attachments[DUBBO_VERSION_KEY])
-
- var resWithException, resValue, resNullValue int32
- if atta {
- resWithException = RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS
- resValue = RESPONSE_VALUE_WITH_ATTACHMENTS
- resNullValue = RESPONSE_NULL_VALUE_WITH_ATTACHMENTS
+ if header.ResponseStatus == Response_OK {
+ if hb {
+ encoder.Encode(nil)
} else {
- resWithException = RESPONSE_WITH_EXCEPTION
- resValue = RESPONSE_VALUE
- resNullValue = RESPONSE_NULL_VALUE
- }
+ // com.alibaba.dubbo.rpc.protocol.dubbo.DubboCodec.DubboCodec.java
+ // v2.7.1 line191 encodeResponseData
- if e, ok := ret.(error); ok { // throw error
- encoder.Encode(resWithException)
- if t, ok := e.(Throwabler); ok {
- encoder.Encode(t)
- } else {
- encoder.Encode(e.Error())
- }
- } else {
- if ret == nil {
- encoder.Encode(resNullValue)
- } else {
- encoder.Encode(resValue)
- encoder.Encode(ret) // result
- }
- }
+ atta := isSupportResponseAttachment(attachments[DUBBO_VERSION_KEY])
- if atta {
- encoder.Encode(attachments) // attachments
+ var resWithException, resValue, resNullValue int32
+ if atta {
+ resWithException = RESPONSE_WITH_EXCEPTION_WITH_ATTACHMENTS
+ resValue = RESPONSE_VALUE_WITH_ATTACHMENTS
+ resNullValue = RESPONSE_NULL_VALUE_WITH_ATTACHMENTS
+ } else {
+ resWithException = RESPONSE_WITH_EXCEPTION
+ resValue = RESPONSE_VALUE
+ resNullValue = RESPONSE_NULL_VALUE
+ }
+
+ if e, ok := ret.(error); ok { // throw error
+ encoder.Encode(resWithException)
+ if t, ok := e.(Throwabler); ok {
+ encoder.Encode(t)
+ } else {
+ encoder.Encode(e.Error())
+ }
+ } else {
+ if ret == nil {
+ encoder.Encode(resNullValue)
+ } else {
+ encoder.Encode(resValue)
+ encoder.Encode(ret) // result
+ }
+ }
+
+ if atta {
+ encoder.Encode(attachments) // attachments
+ }
}
} else {
// com.alibaba.dubbo.remoting.exchange.codec.ExchangeCodec