2022-08-28 21:41:58 +02:00
|
|
|
package measurexlite
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
|
|
|
|
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
|
|
|
"github.com/ooni/probe-cli/v3/internal/runtimex"
|
|
|
|
)
|
|
|
|
|
|
|
|
// NewFailure creates an OONI failure from an error. If the error is nil,
|
|
|
|
// we return nil. If the error is not already an ErrWrapper, it's converted
|
|
|
|
// to an ErrWrapper. If the ErrWrapper's Failure is not empty, we return its
|
|
|
|
// string representation. Otherwise we return a string indicating that
|
|
|
|
// an ErrWrapper has an empty failure (should not happen).
|
|
|
|
//
|
|
|
|
// See https://github.com/ooni/spec/blob/master/data-formats/df-007-errors.md
|
|
|
|
// for more information about OONI failures.
|
|
|
|
func NewFailure(err error) *string {
|
|
|
|
if err == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
// The following code guarantees that the error is always wrapped even
|
|
|
|
// when we could not actually hit our code that does the wrapping. A case
|
|
|
|
// in which this could happen is with context deadline for HTTP when you
|
|
|
|
// have wrapped the underlying dialers but not the Transport.
|
|
|
|
var errWrapper *netxlite.ErrWrapper
|
|
|
|
if !errors.As(err, &errWrapper) {
|
|
|
|
err := netxlite.NewTopLevelGenericErrWrapper(err)
|
|
|
|
couldConvert := errors.As(err, &errWrapper)
|
2022-08-31 18:40:27 +02:00
|
|
|
runtimex.Assert(couldConvert, "we should have an ErrWrapper here")
|
2022-08-28 21:41:58 +02:00
|
|
|
}
|
|
|
|
s := errWrapper.Failure
|
|
|
|
if s == "" {
|
|
|
|
s = "unknown_failure: errWrapper.Failure is empty"
|
|
|
|
}
|
|
|
|
return &s
|
|
|
|
}
|