ccb3a644e1
We will move the sane part of this package to i/netxlite/errorsx and we will move the rest to i/e/legacy/errorsx. What is the sane part? The sane part is error classifiers plus the definition of ErrWrapper. The rest, including the rules on how to decide whether an operation is major, are tricky and we should consider them legacy and replace them with rules that are more easy to understand and reason on. Part of https://github.com/ooni/probe/issues/1591
78 lines
1.8 KiB
Go
78 lines
1.8 KiB
Go
package errorsx
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
)
|
|
|
|
// Dialer establishes network connections.
|
|
type Dialer interface {
|
|
// DialContext behaves like net.Dialer.DialContext.
|
|
DialContext(ctx context.Context, network, address string) (net.Conn, error)
|
|
}
|
|
|
|
// ErrorWrapperDialer is a dialer that performs error wrapping. The connection
|
|
// returned by the DialContext function will also perform error wrapping.
|
|
type ErrorWrapperDialer struct {
|
|
// Dialer is the underlying dialer.
|
|
Dialer
|
|
}
|
|
|
|
// DialContext implements Dialer.DialContext.
|
|
func (d *ErrorWrapperDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
|
conn, err := d.Dialer.DialContext(ctx, network, address)
|
|
if err != nil {
|
|
return nil, &ErrWrapper{
|
|
Failure: ClassifyGenericError(err),
|
|
Operation: ConnectOperation,
|
|
WrappedErr: err,
|
|
}
|
|
}
|
|
return &errorWrapperConn{Conn: conn}, nil
|
|
}
|
|
|
|
// errorWrapperConn is a net.Conn that performs error wrapping.
|
|
type errorWrapperConn struct {
|
|
// Conn is the underlying connection.
|
|
net.Conn
|
|
}
|
|
|
|
// Read implements net.Conn.Read.
|
|
func (c *errorWrapperConn) Read(b []byte) (int, error) {
|
|
count, err := c.Conn.Read(b)
|
|
if err != nil {
|
|
return 0, &ErrWrapper{
|
|
Failure: ClassifyGenericError(err),
|
|
Operation: ReadOperation,
|
|
WrappedErr: err,
|
|
}
|
|
}
|
|
return count, nil
|
|
}
|
|
|
|
// Write implements net.Conn.Write.
|
|
func (c *errorWrapperConn) Write(b []byte) (int, error) {
|
|
count, err := c.Conn.Write(b)
|
|
if err != nil {
|
|
return 0, &ErrWrapper{
|
|
Failure: ClassifyGenericError(err),
|
|
Operation: WriteOperation,
|
|
WrappedErr: err,
|
|
}
|
|
}
|
|
return count, nil
|
|
}
|
|
|
|
// Close implements net.Conn.Close.
|
|
func (c *errorWrapperConn) Close() error {
|
|
err := c.Conn.Close()
|
|
if err != nil {
|
|
return &ErrWrapper{
|
|
Failure: ClassifyGenericError(err),
|
|
Operation: CloseOperation,
|
|
WrappedErr: err,
|
|
}
|
|
}
|
|
return nil
|
|
}
|