ooni-probe-cli/internal/errorsx/resolver.go
Simone Basso ccb3a644e1
refactor(errorsx): prepare for splitting the package (#476)
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
2021-09-07 15:46:32 +02:00

65 lines
1.6 KiB
Go

package errorsx
import (
"context"
"errors"
)
// Resolver is a DNS resolver. The *net.Resolver used by Go implements
// this interface, but other implementations are possible.
type Resolver interface {
// LookupHost resolves a hostname to a list of IP addresses.
LookupHost(ctx context.Context, hostname string) (addrs []string, err error)
}
// ErrorWrapperResolver is a Resolver that knows about wrapping errors.
type ErrorWrapperResolver struct {
Resolver
}
var _ Resolver = &ErrorWrapperResolver{}
// LookupHost implements Resolver.LookupHost
func (r *ErrorWrapperResolver) LookupHost(ctx context.Context, hostname string) ([]string, error) {
addrs, err := r.Resolver.LookupHost(ctx, hostname)
err = SafeErrWrapperBuilder{
Classifier: ClassifyResolverError,
Error: err,
Operation: ResolveOperation,
}.MaybeBuild()
return addrs, err
}
// 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 ClassifyGenericError(err)
}
type resolverNetworker interface {
Network() string
}
// Network implements Resolver.Network.
func (r *ErrorWrapperResolver) Network() string {
if rn, ok := r.Resolver.(resolverNetworker); ok {
return rn.Network()
}
return "errorWrapper"
}
type resolverAddresser interface {
Address() string
}
// Address implements Resolver.Address.
func (r *ErrorWrapperResolver) Address() string {
if ra, ok := r.Resolver.(resolverAddresser); ok {
return ra.Address()
}
return ""
}