Skip to content

Commit 4d13aab

Browse files
akshayjshahgopherbot
authored andcommitted
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 <[email protected]> Auto-Submit: Damien Neil <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Damien Neil <[email protected]> Reviewed-by: David Chase <[email protected]>
1 parent bcd1ac7 commit 4d13aab

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

src/net/http/h2_error.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2022 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build !nethttpomithttp2
6+
// +build !nethttpomithttp2
7+
8+
package http
9+
10+
import (
11+
"reflect"
12+
)
13+
14+
func (e http2StreamError) As(target any) bool {
15+
dst := reflect.ValueOf(target).Elem()
16+
dstType := dst.Type()
17+
if dstType.Kind() != reflect.Struct {
18+
return false
19+
}
20+
src := reflect.ValueOf(e)
21+
srcType := src.Type()
22+
numField := srcType.NumField()
23+
if dstType.NumField() != numField {
24+
return false
25+
}
26+
for i := 0; i < numField; i++ {
27+
sf := srcType.Field(i)
28+
df := dstType.Field(i)
29+
if sf.Name != df.Name || !sf.Type.ConvertibleTo(df.Type) {
30+
return false
31+
}
32+
}
33+
for i := 0; i < numField; i++ {
34+
df := dst.Field(i)
35+
df.Set(src.Field(i).Convert(df.Type()))
36+
}
37+
return true
38+
}

src/net/http/h2_error_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2022 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build !nethttpomithttp2
6+
// +build !nethttpomithttp2
7+
8+
package http
9+
10+
import (
11+
"errors"
12+
"fmt"
13+
"testing"
14+
)
15+
16+
type externalStreamErrorCode uint32
17+
18+
type externalStreamError struct {
19+
StreamID uint32
20+
Code externalStreamErrorCode
21+
Cause error
22+
}
23+
24+
func (e externalStreamError) Error() string {
25+
return fmt.Sprintf("ID %v, code %v", e.StreamID, e.Code)
26+
}
27+
28+
func TestStreamError(t *testing.T) {
29+
var target externalStreamError
30+
streamErr := http2streamError(42, http2ErrCodeProtocol)
31+
ok := errors.As(streamErr, &target)
32+
if !ok {
33+
t.Fatalf("errors.As failed")
34+
}
35+
if target.StreamID != streamErr.StreamID {
36+
t.Errorf("got StreamID %v, expected %v", target.StreamID, streamErr.StreamID)
37+
}
38+
if target.Cause != streamErr.Cause {
39+
t.Errorf("got Cause %v, expected %v", target.Cause, streamErr.Cause)
40+
}
41+
if uint32(target.Code) != uint32(streamErr.Code) {
42+
t.Errorf("got Code %v, expected %v", target.Code, streamErr.Code)
43+
}
44+
}

0 commit comments

Comments
 (0)