mirror of
https://github.com/golang/go
synced 2024-11-16 22:14:45 -07:00
net/http: add errors.As support for x/net/http2.StreamError
To make it easier to extract the HTTP/2 error code (if any) from net/http errors, implement an As method on the vendored copy of golang.org/x/net/http2.StreamError. The new As method lets users work with the vendored error type as though it were the x/net/http2 StreamError. Fixes #53896. Change-Id: Ib18eb428adc05a3c0e19a946ece936e2378e1c7c Reviewed-on: https://go-review.googlesource.com/c/go/+/425104 Run-TryBot: Damien Neil <dneil@google.com> Auto-Submit: Damien Neil <dneil@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Damien Neil <dneil@google.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
bcd1ac7120
commit
4d13aabdf6
38
src/net/http/h2_error.go
Normal file
38
src/net/http/h2_error.go
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !nethttpomithttp2
|
||||
// +build !nethttpomithttp2
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func (e http2StreamError) As(target any) bool {
|
||||
dst := reflect.ValueOf(target).Elem()
|
||||
dstType := dst.Type()
|
||||
if dstType.Kind() != reflect.Struct {
|
||||
return false
|
||||
}
|
||||
src := reflect.ValueOf(e)
|
||||
srcType := src.Type()
|
||||
numField := srcType.NumField()
|
||||
if dstType.NumField() != numField {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < numField; i++ {
|
||||
sf := srcType.Field(i)
|
||||
df := dstType.Field(i)
|
||||
if sf.Name != df.Name || !sf.Type.ConvertibleTo(df.Type) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
for i := 0; i < numField; i++ {
|
||||
df := dst.Field(i)
|
||||
df.Set(src.Field(i).Convert(df.Type()))
|
||||
}
|
||||
return true
|
||||
}
|
44
src/net/http/h2_error_test.go
Normal file
44
src/net/http/h2_error_test.go
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !nethttpomithttp2
|
||||
// +build !nethttpomithttp2
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type externalStreamErrorCode uint32
|
||||
|
||||
type externalStreamError struct {
|
||||
StreamID uint32
|
||||
Code externalStreamErrorCode
|
||||
Cause error
|
||||
}
|
||||
|
||||
func (e externalStreamError) Error() string {
|
||||
return fmt.Sprintf("ID %v, code %v", e.StreamID, e.Code)
|
||||
}
|
||||
|
||||
func TestStreamError(t *testing.T) {
|
||||
var target externalStreamError
|
||||
streamErr := http2streamError(42, http2ErrCodeProtocol)
|
||||
ok := errors.As(streamErr, &target)
|
||||
if !ok {
|
||||
t.Fatalf("errors.As failed")
|
||||
}
|
||||
if target.StreamID != streamErr.StreamID {
|
||||
t.Errorf("got StreamID %v, expected %v", target.StreamID, streamErr.StreamID)
|
||||
}
|
||||
if target.Cause != streamErr.Cause {
|
||||
t.Errorf("got Cause %v, expected %v", target.Cause, streamErr.Cause)
|
||||
}
|
||||
if uint32(target.Code) != uint32(streamErr.Code) {
|
||||
t.Errorf("got Code %v, expected %v", target.Code, streamErr.Code)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user