mirror of https://github.com/grpc/grpc-go.git
Make Dial() return original error
This commit is contained in:
parent
b41c9e8e14
commit
7c6eabc607
|
@ -435,7 +435,10 @@ func (cc *ClientConn) resetAddrConn(addr Address, skipWait bool, tearDownErr err
|
|||
ac.cc.mu.Unlock()
|
||||
ac.tearDown(err)
|
||||
}
|
||||
return fmt.Errorf("failed to create transport: %v", err)
|
||||
if e, ok := err.(transport.ConnectionError); ok && !e.Temporary() {
|
||||
return e.OriginalError()
|
||||
}
|
||||
return err
|
||||
}
|
||||
// Start to monitor the error status of transport.
|
||||
go ac.transportMonitor()
|
||||
|
|
|
@ -2275,10 +2275,12 @@ func testClientRequestBodyError_Cancel_StreamingInput(t *testing.T, e env) {
|
|||
|
||||
const clientAlwaysFailCredErrorMsg = "clientAlwaysFailCred always fails"
|
||||
|
||||
var clientAlwaysFailCredError = errors.New(clientAlwaysFailCredErrorMsg)
|
||||
|
||||
type clientAlwaysFailCred struct{}
|
||||
|
||||
func (c clientAlwaysFailCred) ClientHandshake(addr string, rawConn net.Conn, timeout time.Duration) (_ net.Conn, _ credentials.AuthInfo, err error) {
|
||||
return nil, nil, errors.New(clientAlwaysFailCredErrorMsg)
|
||||
return nil, nil, clientAlwaysFailCredError
|
||||
}
|
||||
func (c clientAlwaysFailCred) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) {
|
||||
return rawConn, nil, nil
|
||||
|
@ -2298,8 +2300,8 @@ func TestDialWithBlockErrorOnBadCertificates(t *testing.T) {
|
|||
)
|
||||
opts = append(opts, grpc.WithTransportCredentials(clientAlwaysFailCred{}), grpc.WithBlock())
|
||||
te.cc, err = grpc.Dial(te.srvAddr, opts...)
|
||||
if !strings.Contains(err.Error(), clientAlwaysFailCredErrorMsg) {
|
||||
te.t.Fatalf("Dial(%q) = %v, want err.Error() contains %q", te.srvAddr, err, clientAlwaysFailCredErrorMsg)
|
||||
if err != clientAlwaysFailCredError {
|
||||
te.t.Fatalf("Dial(%q) = %v, want %v", te.srvAddr, err, clientAlwaysFailCredError)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ Cl
|
|||
scheme := "http"
|
||||
conn, connErr := dial(opts.Dialer, ctx, addr)
|
||||
if connErr != nil {
|
||||
return nil, ConnectionErrorf(true, "transport: %v", connErr)
|
||||
return nil, ConnectionErrorf(true, connErr, "transport: %v", connErr)
|
||||
}
|
||||
var authInfo credentials.AuthInfo
|
||||
if creds := opts.TransportCredentials; creds != nil {
|
||||
|
@ -130,7 +130,7 @@ func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ Cl
|
|||
}
|
||||
if connErr != nil {
|
||||
// Credentials handshake error is not a temporary error.
|
||||
return nil, ConnectionErrorf(false, "transport: %v", connErr)
|
||||
return nil, ConnectionErrorf(false, connErr, "transport: %v", connErr)
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
|
@ -174,11 +174,11 @@ func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ Cl
|
|||
n, err := t.conn.Write(clientPreface)
|
||||
if err != nil {
|
||||
t.Close()
|
||||
return nil, ConnectionErrorf(true, "transport: %v", err)
|
||||
return nil, ConnectionErrorf(true, err, "transport: %v", err)
|
||||
}
|
||||
if n != len(clientPreface) {
|
||||
t.Close()
|
||||
return nil, ConnectionErrorf(true, "transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface))
|
||||
return nil, ConnectionErrorf(true, err, "transport: preface mismatch, wrote %d bytes; want %d", n, len(clientPreface))
|
||||
}
|
||||
if initialWindowSize != defaultWindowSize {
|
||||
err = t.framer.writeSettings(true, http2.Setting{
|
||||
|
@ -190,13 +190,13 @@ func newHTTP2Client(ctx context.Context, addr string, opts ConnectOptions) (_ Cl
|
|||
}
|
||||
if err != nil {
|
||||
t.Close()
|
||||
return nil, ConnectionErrorf(true, "transport: %v", err)
|
||||
return nil, ConnectionErrorf(true, err, "transport: %v", err)
|
||||
}
|
||||
// Adjust the connection flow control window if needed.
|
||||
if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 {
|
||||
if err := t.framer.writeWindowUpdate(true, 0, delta); err != nil {
|
||||
t.Close()
|
||||
return nil, ConnectionErrorf(true, "transport: %v", err)
|
||||
return nil, ConnectionErrorf(true, err, "transport: %v", err)
|
||||
}
|
||||
}
|
||||
go t.controller()
|
||||
|
@ -406,7 +406,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
|
|||
}
|
||||
if err != nil {
|
||||
t.notifyError(err)
|
||||
return nil, ConnectionErrorf(true, "transport: %v", err)
|
||||
return nil, ConnectionErrorf(true, err, "transport: %v", err)
|
||||
}
|
||||
}
|
||||
t.writableChan <- 0
|
||||
|
@ -620,7 +620,7 @@ func (t *http2Client) Write(s *Stream, data []byte, opts *Options) error {
|
|||
// invoked.
|
||||
if err := t.framer.writeData(forceFlush, s.id, endStream, p); err != nil {
|
||||
t.notifyError(err)
|
||||
return ConnectionErrorf(true, "transport: %v", err)
|
||||
return ConnectionErrorf(true, err, "transport: %v", err)
|
||||
}
|
||||
if t.framer.adjustNumWriters(-1) == 0 {
|
||||
t.framer.flushWrite()
|
||||
|
@ -668,7 +668,7 @@ func (t *http2Client) updateWindow(s *Stream, n uint32) {
|
|||
func (t *http2Client) handleData(f *http2.DataFrame) {
|
||||
size := len(f.Data())
|
||||
if err := t.fc.onData(uint32(size)); err != nil {
|
||||
t.notifyError(ConnectionErrorf(true, "%v", err))
|
||||
t.notifyError(ConnectionErrorf(true, err, "%v", err))
|
||||
return
|
||||
}
|
||||
// Select the right stream to dispatch.
|
||||
|
|
|
@ -111,12 +111,12 @@ func newHTTP2Server(conn net.Conn, maxStreams uint32, authInfo credentials.AuthI
|
|||
Val: uint32(initialWindowSize)})
|
||||
}
|
||||
if err := framer.writeSettings(true, settings...); err != nil {
|
||||
return nil, ConnectionErrorf(true, "transport: %v", err)
|
||||
return nil, ConnectionErrorf(true, err, "transport: %v", err)
|
||||
}
|
||||
// Adjust the connection flow control window if needed.
|
||||
if delta := uint32(initialConnWindowSize - defaultWindowSize); delta > 0 {
|
||||
if err := framer.writeWindowUpdate(true, 0, delta); err != nil {
|
||||
return nil, ConnectionErrorf(true, "transport: %v", err)
|
||||
return nil, ConnectionErrorf(true, err, "transport: %v", err)
|
||||
}
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
|
@ -448,7 +448,7 @@ func (t *http2Server) writeHeaders(s *Stream, b *bytes.Buffer, endStream bool) e
|
|||
}
|
||||
if err != nil {
|
||||
t.Close()
|
||||
return ConnectionErrorf(true, "transport: %v", err)
|
||||
return ConnectionErrorf(true, err, "transport: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -568,7 +568,7 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
|
|||
}
|
||||
if err := t.framer.writeHeaders(false, p); err != nil {
|
||||
t.Close()
|
||||
return ConnectionErrorf(true, "transport: %v", err)
|
||||
return ConnectionErrorf(true, err, "transport: %v", err)
|
||||
}
|
||||
t.writableChan <- 0
|
||||
}
|
||||
|
@ -642,7 +642,7 @@ func (t *http2Server) Write(s *Stream, data []byte, opts *Options) error {
|
|||
}
|
||||
if err := t.framer.writeData(forceFlush, s.id, false, p); err != nil {
|
||||
t.Close()
|
||||
return ConnectionErrorf(true, "transport: %v", err)
|
||||
return ConnectionErrorf(true, err, "transport: %v", err)
|
||||
}
|
||||
if t.framer.adjustNumWriters(-1) == 0 {
|
||||
t.framer.flushWrite()
|
||||
|
|
|
@ -485,18 +485,20 @@ func StreamErrorf(c codes.Code, format string, a ...interface{}) StreamError {
|
|||
}
|
||||
|
||||
// ConnectionErrorf creates an ConnectionError with the specified error description.
|
||||
func ConnectionErrorf(temp bool, format string, a ...interface{}) ConnectionError {
|
||||
func ConnectionErrorf(temp bool, e error, format string, a ...interface{}) ConnectionError {
|
||||
return ConnectionError{
|
||||
Desc: fmt.Sprintf(format, a...),
|
||||
temp: temp,
|
||||
Desc: fmt.Sprintf(format, a...),
|
||||
temp: temp,
|
||||
origErr: e,
|
||||
}
|
||||
}
|
||||
|
||||
// ConnectionError is an error that results in the termination of the
|
||||
// entire connection and the retry of all the active streams.
|
||||
type ConnectionError struct {
|
||||
Desc string
|
||||
temp bool
|
||||
Desc string
|
||||
temp bool
|
||||
origErr error
|
||||
}
|
||||
|
||||
func (e ConnectionError) Error() string {
|
||||
|
@ -508,6 +510,11 @@ func (e ConnectionError) Temporary() bool {
|
|||
return e.temp
|
||||
}
|
||||
|
||||
// OriginalError returns the original error of this connection error.
|
||||
func (e ConnectionError) OriginalError() error {
|
||||
return e.origErr
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrConnClosing indicates that the transport is closing.
|
||||
ErrConnClosing = ConnectionError{Desc: "transport is closing", temp: true}
|
||||
|
|
Loading…
Reference in New Issue