diff --git a/internal/errorsx/dialer.go b/internal/errorsx/dialer.go index 4a8c733..9e9a181 100644 --- a/internal/errorsx/dialer.go +++ b/internal/errorsx/dialer.go @@ -23,7 +23,7 @@ func (d *ErrorWrapperDialer) DialContext(ctx context.Context, network, address s conn, err := d.Dialer.DialContext(ctx, network, address) if err != nil { return nil, &ErrWrapper{ - Failure: toFailureString(err), + Failure: ClassifyGenericError(err), Operation: ConnectOperation, WrappedErr: err, } @@ -42,7 +42,7 @@ func (c *errorWrapperConn) Read(b []byte) (int, error) { count, err := c.Conn.Read(b) if err != nil { return 0, &ErrWrapper{ - Failure: toFailureString(err), + Failure: ClassifyGenericError(err), Operation: ReadOperation, WrappedErr: err, } @@ -55,7 +55,7 @@ func (c *errorWrapperConn) Write(b []byte) (int, error) { count, err := c.Conn.Write(b) if err != nil { return 0, &ErrWrapper{ - Failure: toFailureString(err), + Failure: ClassifyGenericError(err), Operation: WriteOperation, WrappedErr: err, } @@ -68,7 +68,7 @@ func (c *errorWrapperConn) Close() error { err := c.Conn.Close() if err != nil { return &ErrWrapper{ - Failure: toFailureString(err), + Failure: ClassifyGenericError(err), Operation: CloseOperation, WrappedErr: err, } diff --git a/internal/errorsx/errno.go b/internal/errorsx/errno.go index 0a101bc..fb873d4 100644 --- a/internal/errorsx/errno.go +++ b/internal/errorsx/errno.go @@ -1,5 +1,5 @@ // Code generated by go generate; DO NOT EDIT. -// Generated: 2021-09-07 14:56:43.206193 +0200 CEST m=+0.141131209 +// Generated: 2021-09-07 15:15:03.350386 +0200 CEST m=+0.135456751 package errorsx @@ -60,10 +60,10 @@ const ( FailureJSONParseError = "json_parse_error" ) -// toSyscallErr converts a syscall error to the +// classifySyscallError converts a syscall error to the // proper OONI error. Returns the OONI error string // on success, an empty string otherwise. -func toSyscallErr(err error) string { +func classifySyscallError(err error) string { // filter out system errors: necessary to detect all windows errors // https://github.com/ooni/probe/issues/1526 describes the problem // of mapping localized windows errors. diff --git a/internal/errorsx/errno_test.go b/internal/errorsx/errno_test.go index 2afbc87..cee89b5 100644 --- a/internal/errorsx/errno_test.go +++ b/internal/errorsx/errno_test.go @@ -1,5 +1,5 @@ // Code generated by go generate; DO NOT EDIT. -// Generated: 2021-09-07 14:56:43.25305 +0200 CEST m=+0.187989417 +// Generated: 2021-09-07 15:15:03.398087 +0200 CEST m=+0.183158793 package errorsx @@ -10,94 +10,94 @@ import ( ) func TestToSyscallErr(t *testing.T) { - if v := toSyscallErr(io.EOF); v != "" { + if v := classifySyscallError(io.EOF); v != "" { t.Fatalf("expected empty string, got '%s'", v) } - if v := toSyscallErr(ECANCELED); v != FailureOperationCanceled { + if v := classifySyscallError(ECANCELED); v != FailureOperationCanceled { t.Fatalf("expected '%s', got '%s'", FailureOperationCanceled, v) } - if v := toSyscallErr(ECONNREFUSED); v != FailureConnectionRefused { + if v := classifySyscallError(ECONNREFUSED); v != FailureConnectionRefused { t.Fatalf("expected '%s', got '%s'", FailureConnectionRefused, v) } - if v := toSyscallErr(ECONNRESET); v != FailureConnectionReset { + if v := classifySyscallError(ECONNRESET); v != FailureConnectionReset { t.Fatalf("expected '%s', got '%s'", FailureConnectionReset, v) } - if v := toSyscallErr(EHOSTUNREACH); v != FailureHostUnreachable { + if v := classifySyscallError(EHOSTUNREACH); v != FailureHostUnreachable { t.Fatalf("expected '%s', got '%s'", FailureHostUnreachable, v) } - if v := toSyscallErr(ETIMEDOUT); v != FailureTimedOut { + if v := classifySyscallError(ETIMEDOUT); v != FailureTimedOut { t.Fatalf("expected '%s', got '%s'", FailureTimedOut, v) } - if v := toSyscallErr(EAFNOSUPPORT); v != FailureAddressFamilyNotSupported { + if v := classifySyscallError(EAFNOSUPPORT); v != FailureAddressFamilyNotSupported { t.Fatalf("expected '%s', got '%s'", FailureAddressFamilyNotSupported, v) } - if v := toSyscallErr(EADDRINUSE); v != FailureAddressInUse { + if v := classifySyscallError(EADDRINUSE); v != FailureAddressInUse { t.Fatalf("expected '%s', got '%s'", FailureAddressInUse, v) } - if v := toSyscallErr(EADDRNOTAVAIL); v != FailureAddressNotAvailable { + if v := classifySyscallError(EADDRNOTAVAIL); v != FailureAddressNotAvailable { t.Fatalf("expected '%s', got '%s'", FailureAddressNotAvailable, v) } - if v := toSyscallErr(EISCONN); v != FailureAlreadyConnected { + if v := classifySyscallError(EISCONN); v != FailureAlreadyConnected { t.Fatalf("expected '%s', got '%s'", FailureAlreadyConnected, v) } - if v := toSyscallErr(EFAULT); v != FailureBadAddress { + if v := classifySyscallError(EFAULT); v != FailureBadAddress { t.Fatalf("expected '%s', got '%s'", FailureBadAddress, v) } - if v := toSyscallErr(EBADF); v != FailureBadFileDescriptor { + if v := classifySyscallError(EBADF); v != FailureBadFileDescriptor { t.Fatalf("expected '%s', got '%s'", FailureBadFileDescriptor, v) } - if v := toSyscallErr(ECONNABORTED); v != FailureConnectionAborted { + if v := classifySyscallError(ECONNABORTED); v != FailureConnectionAborted { t.Fatalf("expected '%s', got '%s'", FailureConnectionAborted, v) } - if v := toSyscallErr(EALREADY); v != FailureConnectionAlreadyInProgress { + if v := classifySyscallError(EALREADY); v != FailureConnectionAlreadyInProgress { t.Fatalf("expected '%s', got '%s'", FailureConnectionAlreadyInProgress, v) } - if v := toSyscallErr(EDESTADDRREQ); v != FailureDestinationAddressRequired { + if v := classifySyscallError(EDESTADDRREQ); v != FailureDestinationAddressRequired { t.Fatalf("expected '%s', got '%s'", FailureDestinationAddressRequired, v) } - if v := toSyscallErr(EINTR); v != FailureInterrupted { + if v := classifySyscallError(EINTR); v != FailureInterrupted { t.Fatalf("expected '%s', got '%s'", FailureInterrupted, v) } - if v := toSyscallErr(EINVAL); v != FailureInvalidArgument { + if v := classifySyscallError(EINVAL); v != FailureInvalidArgument { t.Fatalf("expected '%s', got '%s'", FailureInvalidArgument, v) } - if v := toSyscallErr(EMSGSIZE); v != FailureMessageSize { + if v := classifySyscallError(EMSGSIZE); v != FailureMessageSize { t.Fatalf("expected '%s', got '%s'", FailureMessageSize, v) } - if v := toSyscallErr(ENETDOWN); v != FailureNetworkDown { + if v := classifySyscallError(ENETDOWN); v != FailureNetworkDown { t.Fatalf("expected '%s', got '%s'", FailureNetworkDown, v) } - if v := toSyscallErr(ENETRESET); v != FailureNetworkReset { + if v := classifySyscallError(ENETRESET); v != FailureNetworkReset { t.Fatalf("expected '%s', got '%s'", FailureNetworkReset, v) } - if v := toSyscallErr(ENETUNREACH); v != FailureNetworkUnreachable { + if v := classifySyscallError(ENETUNREACH); v != FailureNetworkUnreachable { t.Fatalf("expected '%s', got '%s'", FailureNetworkUnreachable, v) } - if v := toSyscallErr(ENOBUFS); v != FailureNoBufferSpace { + if v := classifySyscallError(ENOBUFS); v != FailureNoBufferSpace { t.Fatalf("expected '%s', got '%s'", FailureNoBufferSpace, v) } - if v := toSyscallErr(ENOPROTOOPT); v != FailureNoProtocolOption { + if v := classifySyscallError(ENOPROTOOPT); v != FailureNoProtocolOption { t.Fatalf("expected '%s', got '%s'", FailureNoProtocolOption, v) } - if v := toSyscallErr(ENOTSOCK); v != FailureNotASocket { + if v := classifySyscallError(ENOTSOCK); v != FailureNotASocket { t.Fatalf("expected '%s', got '%s'", FailureNotASocket, v) } - if v := toSyscallErr(ENOTCONN); v != FailureNotConnected { + if v := classifySyscallError(ENOTCONN); v != FailureNotConnected { t.Fatalf("expected '%s', got '%s'", FailureNotConnected, v) } - if v := toSyscallErr(EWOULDBLOCK); v != FailureOperationWouldBlock { + if v := classifySyscallError(EWOULDBLOCK); v != FailureOperationWouldBlock { t.Fatalf("expected '%s', got '%s'", FailureOperationWouldBlock, v) } - if v := toSyscallErr(EACCES); v != FailurePermissionDenied { + if v := classifySyscallError(EACCES); v != FailurePermissionDenied { t.Fatalf("expected '%s', got '%s'", FailurePermissionDenied, v) } - if v := toSyscallErr(EPROTONOSUPPORT); v != FailureProtocolNotSupported { + if v := classifySyscallError(EPROTONOSUPPORT); v != FailureProtocolNotSupported { t.Fatalf("expected '%s', got '%s'", FailureProtocolNotSupported, v) } - if v := toSyscallErr(EPROTOTYPE); v != FailureWrongProtocolType { + if v := classifySyscallError(EPROTOTYPE); v != FailureWrongProtocolType { t.Fatalf("expected '%s', got '%s'", FailureWrongProtocolType, v) } - if v := toSyscallErr(syscall.Errno(0)); v != "" { + if v := classifySyscallError(syscall.Errno(0)); v != "" { t.Fatalf("expected empty string, got '%s'", v) } } diff --git a/internal/errorsx/errno_unix.go b/internal/errorsx/errno_unix.go index e12ad06..05fbc9a 100644 --- a/internal/errorsx/errno_unix.go +++ b/internal/errorsx/errno_unix.go @@ -1,5 +1,5 @@ // Code generated by go generate; DO NOT EDIT. -// Generated: 2021-09-07 14:56:43.065762 +0200 CEST m=+0.000698667 +// Generated: 2021-09-07 15:15:03.215384 +0200 CEST m=+0.000452543 package errorsx diff --git a/internal/errorsx/errno_windows.go b/internal/errorsx/errno_windows.go index a7a6097..b3f8b5b 100644 --- a/internal/errorsx/errno_windows.go +++ b/internal/errorsx/errno_windows.go @@ -1,5 +1,5 @@ // Code generated by go generate; DO NOT EDIT. -// Generated: 2021-09-07 14:56:43.179707 +0200 CEST m=+0.114644626 +// Generated: 2021-09-07 15:15:03.324258 +0200 CEST m=+0.109328501 package errorsx diff --git a/internal/errorsx/errorsx.go b/internal/errorsx/errorsx.go index 88e767e..2e34efe 100644 --- a/internal/errorsx/errorsx.go +++ b/internal/errorsx/errorsx.go @@ -85,7 +85,7 @@ func (b SafeErrWrapperBuilder) MaybeBuild() (err error) { if b.Error != nil { classifier := b.Classifier if classifier == nil { - classifier = toFailureString + classifier = ClassifyGenericError } err = &ErrWrapper{ Failure: classifier(b.Error), @@ -100,7 +100,10 @@ func (b SafeErrWrapperBuilder) MaybeBuild() (err error) { // Use errors.Is / errors.As more often, when possible, in this classifier. // These methods are more robust to library changes than strings. // errors.Is / errors.As can only be used when the error is exported. -func toFailureString(err error) string { + +// ClassifyGenericError is the generic classifier mapping an error +// occurred during an operation to an OONI failure string. +func ClassifyGenericError(err error) string { // The list returned here matches the values used by MK unless // explicitly noted otherwise with a comment. @@ -111,7 +114,7 @@ func toFailureString(err error) string { return errwrapper.Error() // we've already wrapped it } - if failure := toSyscallErr(err); failure != "" { + if failure := classifySyscallError(err); failure != "" { return failure } diff --git a/internal/errorsx/errorsx_test.go b/internal/errorsx/errorsx_test.go index a9ff882..32fd625 100644 --- a/internal/errorsx/errorsx_test.go +++ b/internal/errorsx/errorsx_test.go @@ -34,47 +34,47 @@ func TestMaybeBuildFactory(t *testing.T) { func TestToFailureString(t *testing.T) { t.Run("for already wrapped error", func(t *testing.T) { err := SafeErrWrapperBuilder{Error: io.EOF}.MaybeBuild() - if toFailureString(err) != FailureEOFError { + if ClassifyGenericError(err) != FailureEOFError { t.Fatal("unexpected result") } }) t.Run("for context.Canceled", func(t *testing.T) { - if toFailureString(context.Canceled) != FailureInterrupted { + if ClassifyGenericError(context.Canceled) != FailureInterrupted { t.Fatal("unexpected result") } }) t.Run("for operation was canceled error", func(t *testing.T) { - if toFailureString(errors.New("operation was canceled")) != FailureInterrupted { + if ClassifyGenericError(errors.New("operation was canceled")) != FailureInterrupted { t.Fatal("unexpected result") } }) t.Run("for EOF", func(t *testing.T) { - if toFailureString(io.EOF) != FailureEOFError { + if ClassifyGenericError(io.EOF) != FailureEOFError { t.Fatal("unexpected results") } }) t.Run("for canceled", func(t *testing.T) { - if toFailureString(syscall.ECANCELED) != FailureOperationCanceled { + if ClassifyGenericError(syscall.ECANCELED) != FailureOperationCanceled { t.Fatal("unexpected results") } }) t.Run("for connection_refused", func(t *testing.T) { - if toFailureString(syscall.ECONNREFUSED) != FailureConnectionRefused { + if ClassifyGenericError(syscall.ECONNREFUSED) != FailureConnectionRefused { t.Fatal("unexpected results") } }) t.Run("for connection_reset", func(t *testing.T) { - if toFailureString(syscall.ECONNRESET) != FailureConnectionReset { + if ClassifyGenericError(syscall.ECONNRESET) != FailureConnectionReset { t.Fatal("unexpected results") } }) t.Run("for host_unreachable", func(t *testing.T) { - if toFailureString(syscall.EHOSTUNREACH) != FailureHostUnreachable { + if ClassifyGenericError(syscall.EHOSTUNREACH) != FailureHostUnreachable { t.Fatal("unexpected results") } }) t.Run("for system timeout", func(t *testing.T) { - if toFailureString(syscall.ETIMEDOUT) != FailureTimedOut { + if ClassifyGenericError(syscall.ETIMEDOUT) != FailureTimedOut { t.Fatal("unexpected results") } }) @@ -82,12 +82,12 @@ func TestToFailureString(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 1) defer cancel() <-ctx.Done() - if toFailureString(ctx.Err()) != FailureGenericTimeoutError { + if ClassifyGenericError(ctx.Err()) != FailureGenericTimeoutError { t.Fatal("unexpected results") } }) t.Run("for stun's transaction is timed out", func(t *testing.T) { - if toFailureString(stun.ErrTransactionTimeOut) != FailureGenericTimeoutError { + if ClassifyGenericError(stun.ErrTransactionTimeOut) != FailureGenericTimeoutError { t.Fatal("unexpected results") } }) @@ -101,18 +101,18 @@ func TestToFailureString(t *testing.T) { if conn != nil { t.Fatal("expected nil connection here") } - if toFailureString(err) != FailureGenericTimeoutError { + if ClassifyGenericError(err) != FailureGenericTimeoutError { t.Fatal("unexpected results") } }) t.Run("for TLS handshake timeout error", func(t *testing.T) { err := errors.New("net/http: TLS handshake timeout") - if toFailureString(err) != FailureGenericTimeoutError { + if ClassifyGenericError(err) != FailureGenericTimeoutError { t.Fatal("unexpected results") } }) t.Run("for no such host", func(t *testing.T) { - if toFailureString(&net.DNSError{ + if ClassifyGenericError(&net.DNSError{ Err: "no such host", }) != FailureDNSNXDOMAINError { t.Fatal("unexpected results") @@ -121,7 +121,7 @@ func TestToFailureString(t *testing.T) { t.Run("for errors including IPv4 address", func(t *testing.T) { input := errors.New("read tcp 10.0.2.15:56948->93.184.216.34:443: use of closed network connection") expected := "unknown_failure: read tcp [scrubbed]->[scrubbed]: use of closed network connection" - out := toFailureString(input) + out := ClassifyGenericError(input) if out != expected { t.Fatal(cmp.Diff(expected, out)) } @@ -129,7 +129,7 @@ func TestToFailureString(t *testing.T) { t.Run("for errors including IPv6 address", func(t *testing.T) { input := errors.New("read tcp [::1]:56948->[::1]:443: use of closed network connection") expected := "unknown_failure: read tcp [scrubbed]->[scrubbed]: use of closed network connection" - out := toFailureString(input) + out := ClassifyGenericError(input) if out != expected { t.Fatal(cmp.Diff(expected, out)) } @@ -149,7 +149,7 @@ func TestToFailureString(t *testing.T) { if sess != nil { t.Fatal("expected nil session here") } - if toFailureString(err) != FailureGenericTimeoutError { + if ClassifyGenericError(err) != FailureGenericTimeoutError { t.Fatal("unexpected results") } }) @@ -157,51 +157,51 @@ func TestToFailureString(t *testing.T) { func TestClassifyQUICFailure(t *testing.T) { t.Run("for connection_reset", func(t *testing.T) { - if classifyQUICFailure(&quic.StatelessResetError{}) != FailureConnectionReset { + if ClassifyQUICHandshakeError(&quic.StatelessResetError{}) != FailureConnectionReset { t.Fatal("unexpected results") } }) t.Run("for incompatible quic version", func(t *testing.T) { - if classifyQUICFailure(&quic.VersionNegotiationError{}) != FailureQUICIncompatibleVersion { + if ClassifyQUICHandshakeError(&quic.VersionNegotiationError{}) != FailureQUICIncompatibleVersion { t.Fatal("unexpected results") } }) t.Run("for quic connection refused", func(t *testing.T) { - if classifyQUICFailure(&quic.TransportError{ErrorCode: quic.ConnectionRefused}) != FailureConnectionRefused { + if ClassifyQUICHandshakeError(&quic.TransportError{ErrorCode: quic.ConnectionRefused}) != FailureConnectionRefused { t.Fatal("unexpected results") } }) t.Run("for quic handshake timeout", func(t *testing.T) { - if classifyQUICFailure(&quic.HandshakeTimeoutError{}) != FailureGenericTimeoutError { + if ClassifyQUICHandshakeError(&quic.HandshakeTimeoutError{}) != FailureGenericTimeoutError { t.Fatal("unexpected results") } }) t.Run("for QUIC idle connection timeout", func(t *testing.T) { - if classifyQUICFailure(&quic.IdleTimeoutError{}) != FailureGenericTimeoutError { + if ClassifyQUICHandshakeError(&quic.IdleTimeoutError{}) != FailureGenericTimeoutError { t.Fatal("unexpected results") } }) t.Run("for QUIC CRYPTO Handshake", func(t *testing.T) { var err quic.TransportErrorCode = quicTLSAlertHandshakeFailure - if classifyQUICFailure(&quic.TransportError{ErrorCode: err}) != FailureSSLFailedHandshake { + if ClassifyQUICHandshakeError(&quic.TransportError{ErrorCode: err}) != FailureSSLFailedHandshake { t.Fatal("unexpected results") } }) t.Run("for QUIC CRYPTO Invalid Certificate", func(t *testing.T) { var err quic.TransportErrorCode = quicTLSAlertBadCertificate - if classifyQUICFailure(&quic.TransportError{ErrorCode: err}) != FailureSSLInvalidCertificate { + if ClassifyQUICHandshakeError(&quic.TransportError{ErrorCode: err}) != FailureSSLInvalidCertificate { t.Fatal("unexpected results") } }) t.Run("for QUIC CRYPTO Unknown CA", func(t *testing.T) { var err quic.TransportErrorCode = quicTLSAlertUnknownCA - if classifyQUICFailure(&quic.TransportError{ErrorCode: err}) != FailureSSLUnknownAuthority { + if ClassifyQUICHandshakeError(&quic.TransportError{ErrorCode: err}) != FailureSSLUnknownAuthority { t.Fatal("unexpected results") } }) t.Run("for QUIC CRYPTO Bad Hostname", func(t *testing.T) { var err quic.TransportErrorCode = quicTLSUnrecognizedName - if classifyQUICFailure(&quic.TransportError{ErrorCode: err}) != FailureSSLInvalidHostname { + if ClassifyQUICHandshakeError(&quic.TransportError{ErrorCode: err}) != FailureSSLInvalidHostname { t.Fatal("unexpected results") } }) @@ -210,7 +210,7 @@ func TestClassifyQUICFailure(t *testing.T) { func TestClassifyResolveFailure(t *testing.T) { t.Run("for ErrDNSBogon", func(t *testing.T) { - if classifyResolveFailure(ErrDNSBogon) != FailureDNSBogonError { + if ClassifyResolverError(ErrDNSBogon) != FailureDNSBogonError { t.Fatal("unexpected result") } }) @@ -219,19 +219,19 @@ func TestClassifyResolveFailure(t *testing.T) { func TestClassifyTLSFailure(t *testing.T) { t.Run("for x509.HostnameError", func(t *testing.T) { var err x509.HostnameError - if classifyTLSFailure(err) != FailureSSLInvalidHostname { + if ClassifyTLSHandshakeError(err) != FailureSSLInvalidHostname { t.Fatal("unexpected result") } }) t.Run("for x509.UnknownAuthorityError", func(t *testing.T) { var err x509.UnknownAuthorityError - if classifyTLSFailure(err) != FailureSSLUnknownAuthority { + if ClassifyTLSHandshakeError(err) != FailureSSLUnknownAuthority { t.Fatal("unexpected result") } }) t.Run("for x509.CertificateInvalidError", func(t *testing.T) { var err x509.CertificateInvalidError - if classifyTLSFailure(err) != FailureSSLInvalidCertificate { + if ClassifyTLSHandshakeError(err) != FailureSSLInvalidCertificate { t.Fatal("unexpected result") } }) diff --git a/internal/errorsx/internal/generrno/main.go b/internal/errorsx/internal/generrno/main.go index 523c99a..af9a0dd 100644 --- a/internal/errorsx/internal/generrno/main.go +++ b/internal/errorsx/internal/generrno/main.go @@ -194,10 +194,10 @@ func writeGenericFile() { } fileWrite(filep, ")\n\n") - fileWrite(filep, "// toSyscallErr converts a syscall error to the\n") + fileWrite(filep, "// classifySyscallError converts a syscall error to the\n") fileWrite(filep, "// proper OONI error. Returns the OONI error string\n") fileWrite(filep, "// on success, an empty string otherwise.\n") - fileWrite(filep, "func toSyscallErr(err error) string {\n") + fileWrite(filep, "func classifySyscallError(err error) string {\n") fileWrite(filep, "\t// filter out system errors: necessary to detect all windows errors\n") fileWrite(filep, "\t// https://github.com/ooni/probe/issues/1526 describes the problem\n") fileWrite(filep, "\t// of mapping localized windows errors.\n") @@ -235,7 +235,7 @@ func writeGenericTestFile() { fileWrite(filep, ")\n\n") fileWrite(filep, "func TestToSyscallErr(t *testing.T) {\n") - fileWrite(filep, "\tif v := toSyscallErr(io.EOF); v != \"\" {\n") + fileWrite(filep, "\tif v := classifySyscallError(io.EOF); v != \"\" {\n") fileWrite(filep, "\t\tt.Fatalf(\"expected empty string, got '%s'\", v)\n") fileWrite(filep, "\t}\n") @@ -243,14 +243,14 @@ func writeGenericTestFile() { if !spec.IsSystemError() { continue } - filePrintf(filep, "\tif v := toSyscallErr(%s); v != %s {\n", + filePrintf(filep, "\tif v := classifySyscallError(%s); v != %s {\n", spec.AsErrnoName(), spec.AsFailureVar()) filePrintf(filep, "\t\tt.Fatalf(\"expected '%%s', got '%%s'\", %s, v)\n", spec.AsFailureVar()) fileWrite(filep, "\t}\n") } - fileWrite(filep, "\tif v := toSyscallErr(syscall.Errno(0)); v != \"\" {\n") + fileWrite(filep, "\tif v := classifySyscallError(syscall.Errno(0)); v != \"\" {\n") fileWrite(filep, "\t\tt.Fatalf(\"expected empty string, got '%s'\", v)\n") fileWrite(filep, "\t}\n") fileWrite(filep, "}\n") diff --git a/internal/errorsx/quic.go b/internal/errorsx/quic.go index a0c0740..818fb02 100644 --- a/internal/errorsx/quic.go +++ b/internal/errorsx/quic.go @@ -88,7 +88,7 @@ func (d *ErrorWrapperQUICDialer) DialContext( tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlySession, error) { sess, err := d.Dialer.DialContext(ctx, network, host, tlsCfg, cfg) err = SafeErrWrapperBuilder{ - Classifier: classifyQUICFailure, + Classifier: ClassifyQUICHandshakeError, Error: err, Operation: QUICHandshakeOperation, }.MaybeBuild() @@ -98,8 +98,9 @@ func (d *ErrorWrapperQUICDialer) DialContext( return sess, nil } -// classifyQUICFailure is a classifier to translate QUIC errors to OONI error strings. -func classifyQUICFailure(err error) string { +// ClassifyQUICHandshakeError maps an error occurred during the QUIC +// handshake to an OONI failure string. +func ClassifyQUICHandshakeError(err error) string { var versionNegotiation *quic.VersionNegotiationError var statelessReset *quic.StatelessResetError var handshakeTimeout *quic.HandshakeTimeoutError @@ -139,7 +140,7 @@ func classifyQUICFailure(err error) string { return FailureSSLInvalidHostname } } - return toFailureString(err) + return ClassifyGenericError(err) } // TLS alert protocol as defined in RFC8446 diff --git a/internal/errorsx/resolver.go b/internal/errorsx/resolver.go index b5c58f6..42c960c 100644 --- a/internal/errorsx/resolver.go +++ b/internal/errorsx/resolver.go @@ -23,19 +23,20 @@ var _ Resolver = &ErrorWrapperResolver{} func (r *ErrorWrapperResolver) LookupHost(ctx context.Context, hostname string) ([]string, error) { addrs, err := r.Resolver.LookupHost(ctx, hostname) err = SafeErrWrapperBuilder{ - Classifier: classifyResolveFailure, + Classifier: ClassifyResolverError, Error: err, Operation: ResolveOperation, }.MaybeBuild() return addrs, err } -// classifyResolveFailure is a classifier to translate DNS resolving errors to OONI error strings. -func classifyResolveFailure(err error) string { +// ClassifyResolverError maps an error occurred during a domain name +// resolution to the corresponding OONI failure string. +func ClassifyResolverError(err error) string { if errors.Is(err, ErrDNSBogon) { return FailureDNSBogonError // not in MK } - return toFailureString(err) + return ClassifyGenericError(err) } type resolverNetworker interface { diff --git a/internal/errorsx/tls.go b/internal/errorsx/tls.go index f408327..2c05d51 100644 --- a/internal/errorsx/tls.go +++ b/internal/errorsx/tls.go @@ -25,15 +25,16 @@ func (h *ErrorWrapperTLSHandshaker) Handshake( ) (net.Conn, tls.ConnectionState, error) { tlsconn, state, err := h.TLSHandshaker.Handshake(ctx, conn, config) err = SafeErrWrapperBuilder{ - Classifier: classifyTLSFailure, + Classifier: ClassifyTLSHandshakeError, Error: err, Operation: TLSHandshakeOperation, }.MaybeBuild() return tlsconn, state, err } -// classifyTLSFailure is a classifier to translate TLS errors to OONI error strings. -func classifyTLSFailure(err error) string { +// ClassifyTLSHandshakeError maps an error occurred during the TLS +// handshake to an OONI failure string. +func ClassifyTLSHandshakeError(err error) string { var x509HostnameError x509.HostnameError if errors.As(err, &x509HostnameError) { // Test case: https://wrong.host.badssl.com/ @@ -50,5 +51,5 @@ func classifyTLSFailure(err error) string { // Test case: https://expired.badssl.com/ return FailureSSLInvalidCertificate } - return toFailureString(err) + return ClassifyGenericError(err) }