-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add base support for non http error codes - WIP on #895
This currently only supports http and the errors currently codified are based on what errors were seen the most. Some errors have new custom messages - this has been done to errors with changing messages with the new custom message primarely removing the changing parts, usually ip/ports and such.
- Loading branch information
Showing
4 changed files
with
188 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package http | ||
|
||
import ( | ||
"crypto/tls" | ||
"crypto/x509" | ||
"net" | ||
"syscall" | ||
|
||
"github.com/pkg/errors" | ||
"golang.org/x/net/http2" | ||
) | ||
|
||
type errCode uint32 | ||
|
||
const ( | ||
// non specific | ||
defaultErrorCode errCode = 1000 | ||
defaultNetNonTCPErrorCode errCode = 1010 | ||
http2GoAwayErrorCode errCode = 1091 | ||
http2StreamErrorCode errCode = 1092 | ||
http2ConnectionErrorCode errCode = 1093 | ||
// DNS errors | ||
defaultDNSErrorCode errCode = 1100 | ||
dnsNoSuchHostErrorCode errCode = 1101 | ||
// tcp errors | ||
defaultTCPErrorCode errCode = 1200 | ||
tcpBrokenPipeErrorCode errCode = 1201 | ||
tcpDialErrorCode errCode = 1210 | ||
tcpDialTimeoutErrorCode errCode = 1211 | ||
tcpDialRefusedErrorCode errCode = 1212 | ||
tcpResetByPeerErrorCode errCode = 1220 | ||
// TLS errors | ||
defaultTLSErrorCode errCode = 1300 | ||
x509UnknownAuthorityErrorCode errCode = 1310 | ||
x509HostnameErrorCode errCode = 1311 | ||
) | ||
|
||
// If a given errorCode from above need to overwrite the error message this should be provided in | ||
// this map | ||
var customErrorMsgMap = map[errCode]string{ | ||
tcpResetByPeerErrorCode: "write: connection reset by peer", | ||
tcpDialTimeoutErrorCode: "dial: i/o timeout", | ||
tcpDialRefusedErrorCode: "dial: connection refused", | ||
tcpBrokenPipeErrorCode: "write: broken pipe", | ||
dnsNoSuchHostErrorCode: "lookup: no such host", | ||
http2GoAwayErrorCode: "http2: received GoAway", | ||
http2StreamErrorCode: "http2: stream error", | ||
http2ConnectionErrorCode: "http2: connection error", | ||
x509HostnameErrorCode: "x509: certificate doesn't match hostname", | ||
} | ||
|
||
func errorCodeForError(err error) errCode { | ||
switch e := errors.Cause(err).(type) { | ||
case *net.DNSError: | ||
switch e.Err { | ||
case "no such host": // defined as private in the go stdlib | ||
return dnsNoSuchHostErrorCode | ||
default: | ||
return defaultDNSErrorCode | ||
} | ||
case *http2.GoAwayError: | ||
// TODO: Add different error for all errcode for goaway | ||
return http2GoAwayErrorCode | ||
case *http2.StreamError: | ||
// TODO: Add different error for all errcode for stream error | ||
return http2StreamErrorCode | ||
case *http2.ConnectionError: | ||
// TODO: Add different error for all errcode for connetion error | ||
return http2ConnectionErrorCode | ||
case *net.OpError: | ||
if e.Net != "tcp" && e.Net != "tcp6" { | ||
// TODO: figure out how this happens | ||
return defaultNetNonTCPErrorCode | ||
} | ||
if e.Op == "write" { | ||
switch e.Err.Error() { | ||
case syscall.ECONNRESET.Error(): | ||
return tcpResetByPeerErrorCode | ||
case syscall.EPIPE.Error(): | ||
return tcpBrokenPipeErrorCode | ||
} | ||
} | ||
if e.Op == "dial" { | ||
if e.Timeout() { | ||
return tcpDialTimeoutErrorCode | ||
} | ||
switch e.Err.Error() { | ||
case syscall.ECONNREFUSED.Error(): | ||
return tcpDialRefusedErrorCode | ||
} | ||
return tcpDialErrorCode | ||
} | ||
return defaultTCPErrorCode | ||
|
||
case *x509.UnknownAuthorityError: | ||
return x509UnknownAuthorityErrorCode | ||
case *x509.HostnameError: | ||
return x509HostnameErrorCode | ||
case *tls.RecordHeaderError: | ||
return defaultTLSErrorCode | ||
default: | ||
return defaultErrorCode | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package http | ||
|
||
import ( | ||
"fmt" | ||
"net" | ||
"syscall" | ||
"testing" | ||
|
||
"github.com/pkg/errors" | ||
"github.com/stretchr/testify/require" | ||
"golang.org/x/net/http2" | ||
) | ||
|
||
func TestErrorCodeForError(t *testing.T) { | ||
// TODO find better way to test | ||
var ( | ||
nonTCPError = new(net.OpError) | ||
econnreset = new(net.OpError) | ||
epipeerror = new(net.OpError) | ||
econnrefused = new(net.OpError) | ||
tcperror = new(net.OpError) | ||
) | ||
nonTCPError.Net = "something" | ||
|
||
econnreset.Net = "tcp" | ||
econnreset.Op = "write" | ||
econnreset.Err = syscall.ECONNRESET | ||
|
||
epipeerror.Net = "tcp" | ||
epipeerror.Op = "write" | ||
epipeerror.Err = syscall.EPIPE | ||
|
||
econnrefused.Net = "tcp" | ||
econnrefused.Op = "dial" | ||
econnrefused.Err = syscall.ECONNREFUSED | ||
|
||
tcperror.Net = "tcp" | ||
|
||
var testTable = map[error]errCode{ | ||
fmt.Errorf("random error"): defaultErrorCode, | ||
new(http2.ConnectionError): http2ConnectionErrorCode, | ||
new(http2.StreamError): http2StreamErrorCode, | ||
new(http2.GoAwayError): http2GoAwayErrorCode, | ||
nonTCPError: defaultNetNonTCPErrorCode, | ||
econnreset: tcpResetByPeerErrorCode, | ||
epipeerror: tcpBrokenPipeErrorCode, | ||
econnrefused: tcpDialRefusedErrorCode, | ||
tcperror: defaultTCPErrorCode, | ||
} | ||
|
||
for err, code := range testTable { | ||
require.Equalf(t, code, errorCodeForError(err), "Wrong error code for error `%s`", err) | ||
require.Equalf(t, code, errorCodeForError(errors.WithStack(err)), "Wrong error code for error `%s`", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters