Skip to content

Commit a363434

Browse files
nightcitybladenightcityblade
andauthored
fix: preserve wrapped error handling (apache#3580)
* fix: preserve wrapped error handling Use errors.Is for sentinel error checks and retain exporter error chains with %w. Fixes: apache#3560 Signed-off-by: nightcityblade <nightcityblade@gmail.com> * test: cover wrapped error handling * chore: format reflection test --------- Signed-off-by: nightcityblade <nightcityblade@gmail.com> Co-authored-by: nightcityblade <nightcityblade@gmail.com>
1 parent 484ff8f commit a363434

5 files changed

Lines changed: 58 additions & 5 deletions

File tree

otel/trace/exporter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func NewExporter(config *ExporterConfig, customFunc func() (sdktrace.SpanExporte
7474

7575
exporter, err := customFunc()
7676
if err != nil {
77-
err = fmt.Errorf("failed to create %s exporter: %v", config.Exporter, err)
77+
err = fmt.Errorf("failed to create %s exporter: %w", config.Exporter, err)
7878
logger.Errorf("[OTel][Trace] failed to create %s exporter, err=%v", config.Exporter, err)
7979
return
8080
}

otel/trace/exporter_test.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,17 @@ func TestNewExporter_CustomFuncError(t *testing.T) {
7676
ServiceName: "test-service",
7777
}
7878

79+
cause := errors.New("custom func error")
7980
customFunc := func() (sdktrace.SpanExporter, error) {
80-
return nil, errors.New("custom func error")
81+
return nil, cause
8182
}
8283

8384
tracerProvider, propagator, err := NewExporter(config, customFunc)
8485
assert.Nil(t, tracerProvider)
8586
assert.Nil(t, propagator)
8687
require.Error(t, err)
8788
assert.Contains(t, err.Error(), "failed to create test exporter")
89+
require.ErrorIs(t, err, cause)
8890
}
8991

9092
func TestNewExporter_InvalidSampleMode(t *testing.T) {

protocol/jsonrpc/server.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"bufio"
2222
"bytes"
2323
"context"
24+
"errors"
2425
"io"
2526
"mime"
2627
"net"
@@ -124,7 +125,7 @@ func (s *Server) handlePkg(conn net.Conn) {
124125

125126
for {
126127
bufReader := bufio.NewReader(io.LimitReader(conn, MaxHeaderSize))
127-
if _, err := bufReader.Peek(1); err == io.EOF {
128+
if _, err := bufReader.Peek(1); errors.Is(err, io.EOF) {
128129
return
129130
}
130131
r, err := http.ReadRequest(bufReader)
@@ -326,7 +327,7 @@ func serveRequest(ctx context.Context, header map[string]string, body []byte, co
326327
codec := newServerCodec()
327328
err := codec.ReadHeader(header, body)
328329
if err != nil {
329-
if err == io.EOF || err == io.ErrUnexpectedEOF {
330+
if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
330331
return perrors.WithStack(err)
331332
}
332333
return perrors.New("server cannot decode request: " + err.Error())

protocol/triple/reflection/serverreflection.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package reflection
2020

2121
import (
2222
"context"
23+
"errors"
2324
"io"
2425
"slices"
2526
"sort"
@@ -166,7 +167,7 @@ func (s *ReflectionServer) ServerReflectionInfo(ctx context.Context, stream rpb.
166167
sentFileDescriptors := make(map[string]bool)
167168
for {
168169
in, err := stream.Recv()
169-
if err == io.EOF {
170+
if errors.Is(err, io.EOF) {
170171
return nil
171172
}
172173
if err != nil {
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package reflection
19+
20+
import (
21+
"context"
22+
"errors"
23+
"fmt"
24+
"io"
25+
"testing"
26+
)
27+
28+
import (
29+
"github.com/stretchr/testify/require"
30+
)
31+
32+
import (
33+
rpb "dubbo.apache.org/dubbo-go/v3/protocol/triple/reflection/triple_reflection"
34+
)
35+
36+
type recvErrorStream struct {
37+
rpb.ServerReflection_ServerReflectionInfoServer
38+
err error
39+
}
40+
41+
func (s recvErrorStream) Recv() (*rpb.ServerReflectionRequest, error) { return nil, s.err }
42+
43+
func TestServerReflectionInfoRecvError(t *testing.T) {
44+
server := &ReflectionServer{}
45+
require.NoError(t, server.ServerReflectionInfo(context.Background(), recvErrorStream{err: fmt.Errorf("transport: %w", io.EOF)}))
46+
47+
recvErr := errors.New("receive failed")
48+
require.ErrorIs(t, server.ServerReflectionInfo(context.Background(), recvErrorStream{err: recvErr}), recvErr)
49+
}

0 commit comments

Comments
 (0)