From 75ae4b2f1b7853529eb8623298119e2d2ae341c6 Mon Sep 17 00:00:00 2001 From: yuxuanwang <464621663@qq.com> Date: Fri, 8 Dec 2023 20:57:08 +0800 Subject: [PATCH] support dubbo3 unary error compatibility --- .../triple/triple_protocol/handler_compat.go | 26 ++++++++++++++ .../triple_protocol/handler_compat_test.go | 34 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 protocol/triple/triple_protocol/handler_compat_test.go diff --git a/protocol/triple/triple_protocol/handler_compat.go b/protocol/triple/triple_protocol/handler_compat.go index 7c21993f9d..5f0ae8c7ec 100644 --- a/protocol/triple/triple_protocol/handler_compat.go +++ b/protocol/triple/triple_protocol/handler_compat.go @@ -19,12 +19,15 @@ package triple_protocol import ( "context" + "errors" "fmt" + "github.com/golang/protobuf/proto" "net/http" ) import ( "github.com/dubbogo/grpc-go" + "github.com/dubbogo/grpc-go/status" ) import ( @@ -66,6 +69,10 @@ func (t *tripleCompatInterceptor) compatUnaryServerInterceptor(ctx context.Conte if !ok { panic(fmt.Sprintf("%+v is not of type *RPCResult", respRaw)) } + triErr, ok := compatError(err) + if ok { + err = triErr + } // todo(DMwangnima): expose API for users to write response headers and trailers return NewResponse(resp.Rest), err } @@ -133,3 +140,22 @@ func generateCompatUnaryHandlerFunc( return conn.Send(resp.Any()) } } + +func compatError(err error) (*Error, bool) { + s, ok := status.FromError(err) + if !ok { + return nil, ok + } + + triErr := NewError(Code(s.Code()), errors.New(s.Message())) + for _, detail := range s.Details() { + // dubbo3 detail use MessageV1, we need to convert it to MessageV2 + errDetail, e := NewErrorDetail(proto.MessageV2(detail.(proto.Message))) + if e != nil { + return nil, false + } + triErr.AddDetail(errDetail) + } + + return triErr, ok +} diff --git a/protocol/triple/triple_protocol/handler_compat_test.go b/protocol/triple/triple_protocol/handler_compat_test.go new file mode 100644 index 0000000000..b6db68249b --- /dev/null +++ b/protocol/triple/triple_protocol/handler_compat_test.go @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package triple_protocol + +import ( + "github.com/dubbogo/grpc-go/codes" + "github.com/dubbogo/grpc-go/status" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestCompatError(t *testing.T) { + err := status.Error(codes.Code(1234), "user defined") + triErr, ok := compatError(err) + assert.True(t, ok) + assert.Equal(t, Code(1234), triErr.Code()) + assert.Equal(t, "user defined", triErr.Message()) + assert.Equal(t, 1, len(triErr.Details())) +}