distinguish biz error from rpc wire error
diff --git a/cluster/cluster/failover/cluster_invoker.go b/cluster/cluster/failover/cluster_invoker.go
index e13dcf5..d70a399 100644
--- a/cluster/cluster/failover/cluster_invoker.go
+++ b/cluster/cluster/failover/cluster_invoker.go
@@ -19,6 +19,7 @@
import (
"context"
+ "dubbo.apache.org/dubbo-go/v3/protocol/triple/triple_protocol"
"fmt"
)
@@ -83,7 +84,7 @@
invoked = append(invoked, ivk)
// DO INVOKE
result = ivk.Invoke(ctx, invocation)
- if result.Error() != nil {
+ if result.Error() != nil && !isBizError(result.Error()) {
providers = append(providers, ivk.GetURL().Key())
continue
}
@@ -100,13 +101,16 @@
}
}
- return &protocol.RPCResult{
- Err: perrors.Wrap(result.Error(), fmt.Sprintf("Failed to invoke the method %v in the service %v. "+
- "Tried %v times of the providers %v (%v/%v)from the registry %v on the consumer %v using the dubbo version %v. "+
- "Last error is %+v.", methodName, invokerSvc, retries, providers, len(providers), len(invokers),
- invokerUrl, ip, constant.Version, result.Error().Error()),
- ),
- }
+ logger.Errorf(fmt.Sprintf("Failed to invoke the method %v in the service %v. "+
+ "Tried %v times of the providers %v (%v/%v)from the registry %v on the consumer %v using the dubbo version %v. "+
+ "Last error is %+v.", methodName, invokerSvc, retries, providers, len(providers), len(invokers),
+ invokerUrl, ip, constant.Version, result.Error().Error()))
+
+ return result
+}
+
+func isBizError(err error) bool {
+ return triple_protocol.IsWireError(err) && triple_protocol.CodeOf(err) == triple_protocol.CodeBizError
}
func getRetries(invokers []protocol.Invoker, methodName string) int {
diff --git a/protocol/result.go b/protocol/result.go
index 904bce3..d86cac2 100644
--- a/protocol/result.go
+++ b/protocol/result.go
@@ -53,9 +53,10 @@
// RPCResult is default RPC result.
type RPCResult struct {
- Attrs map[string]interface{}
- Err error
- Rest interface{}
+ Attrs map[string]interface{}
+ BizErr error
+ Err error
+ Rest interface{}
}
// SetError sets error.
@@ -68,6 +69,16 @@
return r.Err
}
+// SetBizError sets error.
+func (r *RPCResult) SetBizError(err error) {
+ r.BizErr = err
+}
+
+// BizError gets error. Replaced with error code in triple protocol since 3.2.0
+func (r *RPCResult) BizError() error {
+ return r.BizErr
+}
+
// SetResult sets invoker result.
func (r *RPCResult) SetResult(rest interface{}) {
r.Rest = rest
diff --git a/protocol/triple/triple_protocol/code.go b/protocol/triple/triple_protocol/code.go
index c66074a..60bc67f 100644
--- a/protocol/triple/triple_protocol/code.go
+++ b/protocol/triple/triple_protocol/code.go
@@ -104,6 +104,8 @@
// authentication credentials for the operation.
CodeUnauthenticated Code = 16
+ CodeBizError Code = 17
+
minCode = CodeCanceled
maxCode = CodeUnauthenticated
)
diff --git a/server/server.go b/server/server.go
index 1931d6f..5d9281e 100644
--- a/server/server.go
+++ b/server/server.go
@@ -20,6 +20,7 @@
import (
"context"
+ "dubbo.apache.org/dubbo-go/v3/protocol/triple/triple_protocol"
"fmt"
"sort"
"sync"
@@ -106,7 +107,9 @@
if method, ok := ii.methodMap[name]; ok {
res, err := method.MethodFunc(ctx, args, ii.svc)
result.SetResult(res)
- result.SetError(err)
+ if err != nil {
+ result.SetError(triple_protocol.NewError(triple_protocol.CodeBizError, err))
+ }
return result
}
result.SetError(fmt.Errorf("no match method for %s", name))