go.uber.org/yarpc@v1.72.1/transport/tchannel/error_external_test.go (about) 1 // Copyright (c) 2022 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package tchannel_test 22 23 import ( 24 "bytes" 25 "context" 26 "errors" 27 "net" 28 "testing" 29 "time" 30 31 "github.com/stretchr/testify/assert" 32 "github.com/stretchr/testify/require" 33 "github.com/uber/tchannel-go" 34 "go.uber.org/yarpc/api/transport" 35 ytchannel "go.uber.org/yarpc/transport/tchannel" 36 "go.uber.org/yarpc/yarpcerrors" 37 ) 38 39 func TestResponseErrorMetaIntegration(t *testing.T) { 40 const networkErrMsg = "a network error!" 41 42 // use vanilla TChannel server to force return a system error 43 tchHandler := func(ctx context.Context, call *tchannel.InboundCall) { 44 networkErr := tchannel.NewSystemError(tchannel.ErrCodeNetwork, networkErrMsg) 45 require.NoError(t, call.Response().SendSystemError(networkErr), "failed to send system error") 46 } 47 server, err := tchannel.NewChannel("test", &tchannel.ChannelOptions{ 48 Handler: tchannel.HandlerFunc(tchHandler), 49 }) 50 require.NoError(t, err, "could not create TChannel channel") 51 52 listener, err := net.Listen("tcp", "127.0.0.1:0") 53 require.NoError(t, err, "failed to create listener") 54 server.Serve(listener) 55 defer server.Close() 56 57 // init client 58 clientTransport, err := ytchannel.NewTransport(ytchannel.ServiceName("foo")) 59 require.NoError(t, err, "failed to create TChannel client transport") 60 require.NoError(t, clientTransport.Start(), "could not start client transport") 61 defer func() { assert.NoError(t, clientTransport.Stop(), "did not cleanly shutdown client transport") }() 62 63 client := clientTransport.NewSingleOutbound(listener.Addr().String()) 64 require.NoError(t, client.Start(), "could not start outbound") 65 defer func() { assert.NoError(t, client.Stop(), "did not cleanly shutdown outbound") }() 66 67 // call server 68 ctx, cancel := context.WithTimeout(context.Background(), time.Second) 69 defer cancel() 70 _, err = client.Call(ctx, &transport.Request{ 71 Service: "foo", 72 Body: bytes.NewBufferString("bar"), 73 }) 74 require.Error(t, err, "expected call failure") 75 76 // ensure this is still a `yarpcerrors.Status` error 77 require.True(t, yarpcerrors.IsStatus(err), "expected YARPC status error") 78 require.Equal(t, networkErrMsg, yarpcerrors.FromError(err).Message(), "unexpected 'yarpcerrors' error message") 79 require.Equal(t, networkErrMsg, errors.Unwrap(err).Error(), "unexpected unwrapped error message") 80 assert.IsType(t, &yarpcerrors.Status{}, err, "expected YARPC status type") // ensure type switching still works 81 82 // verify response meta 83 meta := ytchannel.GetResponseErrorMeta(err) 84 require.NotNil(t, meta, "unable to retrieve response meta") 85 assert.Equal(t, tchannel.ErrCodeNetwork.String(), meta.Code.String(), "unexpected response code") 86 }