errbase

package
v1.11.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 22, 2024 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DecodeError

func DecodeError(ctx context.Context, enc EncodedError) error

DecodeError decodes an error.

Can only be called if the EncodedError is set (see IsSet()).

func FormatError

func FormatError(err error, s fmt.State, verb rune)

FormatError formats an error according to s and verb. This is a helper meant for use when implementing the fmt.Formatter interface on custom error objects.

If the error implements errors.Formatter, FormatError calls its FormatError method of f with an errors.Printer configured according to s and verb, and writes the result to s.

Otherwise, if it is a wrapper, FormatError prints out its error prefix, then recurses on its cause.

Otherwise, its Error() text is printed.

func FormatRedactableError

func FormatRedactableError(err error, s redact.SafePrinter, verb rune)

FormatRedactableError formats an error as a safe object.

Note that certain verb/flags combinations are currently not supported, and result in a rendering that considers the entire object as unsafe. For example, %q, %#v are not yet supported.

func Formattable

func Formattable(err error) fmt.Formatter

Formattable wraps an error into a fmt.Formatter which will provide "smart" formatting even if the outer layer of the error does not implement the Formatter interface.

func GetTypeMark

func GetTypeMark(err error) errorspb.ErrorTypeMark

GetTypeMark retrieves the ErrorTypeMark for a given error object. This is meant for use in the markers sub-package.

func RegisterLeafDecoder

func RegisterLeafDecoder(theType TypeKey, decoder LeafDecoder)

RegisterLeafDecoder can be used to register new leaf error types to the library. Registered types will be decoded using their own Go type when an error is decoded. Wrappers that have not been registered will be decoded using the opaqueLeaf type.

Note: if the error type has been migrated from a previous location or a different type, ensure that RegisterTypeMigration() was called prior to RegisterLeafDecoder().

func RegisterLeafEncoder

func RegisterLeafEncoder(theType TypeKey, encoder LeafEncoder)

RegisterLeafEncoder can be used to register new leaf error types to the library. Registered types will be encoded using their own Go type when an error is encoded. Wrappers that have not been registered will be encoded using the opaqueLeaf type.

Note: if the error type has been migrated from a previous location or a different type, ensure that RegisterTypeMigration() was called prior to RegisterLeafEncoder().

func RegisterMultiCauseDecoder

func RegisterMultiCauseDecoder(theType TypeKey, decoder MultiCauseDecoder)

RegisterMultiCauseDecoder can be used to register new multi-cause wrapper types to the library. Registered wrappers will be decoded using their own Go type when an error is decoded. Multi-cause wrappers that have not been registered will be decoded using the opaqueWrapper type.

func RegisterMultiCauseEncoder

func RegisterMultiCauseEncoder(theType TypeKey, encoder MultiCauseEncoder)

RegisterMultiCauseEncoder can be used to register new multi-cause error types to the library. Registered types will be encoded using their own Go type when an error is encoded. Multi-cause wrappers that have not been registered will be encoded using the opaqueWrapper type.

func RegisterSpecialCasePrinter

func RegisterSpecialCasePrinter(fn safeErrorPrinterFn)

RegisterSpecialCasePrinter registers a handler.

func RegisterTypeMigration

func RegisterTypeMigration(previousPkgPath, previousTypeName string, newType error)

RegisterTypeMigration tells the library that the type of the error given as 3rd argument was previously known with type previousTypeName, located at previousPkgPath.

The value of previousTypeName must be the result of calling reflect.TypeOf(err).String() on the original error object. This is usually composed as follows:

[*]<shortpackage>.<errortype>

For example, Go's standard error type has name "*errors.errorString". The asterisk indicates that `errorString` implements the `error` interface via pointer receiver.

Meanwhile, the singleton error type context.DeadlineExceeded has name "context.deadlineExceededError", without asterisk because the type implements `error` by value.

Remember that the short package name inside the error type name and the last component of the package path can be different. This is why they must be specified separately.

func RegisterWrapperDecoder

func RegisterWrapperDecoder(theType TypeKey, decoder WrapperDecoder)

RegisterWrapperDecoder can be used to register new wrapper types to the library. Registered wrappers will be decoded using their own Go type when an error is decoded. Wrappers that have not been registered will be decoded using the opaqueWrapper type.

Note: if the error type has been migrated from a previous location or a different type, ensure that RegisterTypeMigration() was called prior to RegisterWrapperDecoder().

func RegisterWrapperEncoder

func RegisterWrapperEncoder(theType TypeKey, encoder WrapperEncoder)

RegisterWrapperEncoder can be used to register new wrapper types to the library. Registered wrappers will be encoded using their own Go type when an error is encoded. Wrappers that have not been registered will be encoded using the opaqueWrapper type.

Note: if the error type has been migrated from a previous location or a different type, ensure that RegisterTypeMigration() was called prior to RegisterWrapperEncoder().

func RegisterWrapperEncoderWithMessageType

func RegisterWrapperEncoderWithMessageType(
	theType TypeKey, encoder WrapperEncoderWithMessageType,
)

RegisterWrapperEncoderWithMessageType can be used to register new wrapper types to the library. Registered wrappers will be encoded using their own Go type when an error is encoded. Wrappers that have not been registered will be encoded using the opaqueWrapper type.

This function differs from RegisterWrapperEncoder by allowing the caller to explicitly decide whether the wrapper owns the entire error message or not. Otherwise, the relationship is inferred.

Note: if the error type has been migrated from a previous location or a different type, ensure that RegisterTypeMigration() was called prior to RegisterWrapperEncoder().

func SetWarningFn

func SetWarningFn(fn func(context.Context, string, ...interface{}))

SetWarningFn enables configuration of the warning function.

func TestingWithEmptyMigrationRegistry

func TestingWithEmptyMigrationRegistry() (restore func())

TestingWithEmptyMigrationRegistry is intended for use by tests.

func UnwrapAll

func UnwrapAll(err error) error

UnwrapAll accesses the root cause object of the error. If the error has no cause (leaf error), it is returned directly. UnwrapAll treats multi-errors as leaf nodes.

func UnwrapMulti

func UnwrapMulti(err error) []error

UnwrapMulti access the slice of causes that an error contains, if it is a multi-error.

func UnwrapOnce

func UnwrapOnce(err error) (cause error)

UnwrapOnce accesses the direct cause of the error if any, otherwise returns nil.

It supports both errors implementing causer (`Cause()` method, from github.com/pkg/errors) and `Wrapper` (`Unwrap()` method, from the Go 2 error proposal).

UnwrapOnce treats multi-errors (those implementing the `Unwrap() []error` interface as leaf-nodes since they cannot reasonably be iterated through to a single cause. These errors are typically constructed as a result of `fmt.Errorf` which results in a `wrapErrors` instance that contains an interpolated error string along with a list of causes.

The go stdlib does not define output on `Unwrap()` for a multi-cause error, so we default to nil here.

Types

type EncodedError

type EncodedError = errorspb.EncodedError

EncodedError is the type of an encoded (and protobuf-encodable) error.

func EncodeError

func EncodeError(ctx context.Context, err error) EncodedError

EncodeError encodes an error.

type Formatter

type Formatter interface {
	error

	// FormatError prints the receiver's first error.
	// The return value decides what happens in the case
	// FormatError() is used to produce a "short" message,
	// eg. when it is used to implement Error():
	//
	// - if it returns nil, then the short message
	//   contains no more than that produced for this error,
	//   even if the error has a further causal chain.
	//
	// - if it returns non-nil, then the short message
	//   contains the value printed by this error,
	//   followed by that of its causal chain.
	//   (e.g. thiserror: itscause: furthercause)
	//
	// Note that all the causal chain is reported in verbose reports in
	// any case.
	FormatError(p Printer) (next error)
}

A Formatter formats error messages.

NB: Consider implementing SafeFormatter instead. This will ensure that error displays can distinguish bits that are PII-safe.

type LeafDecoder

type LeafDecoder = func(ctx context.Context, msg string, safeDetails []string, payload proto.Message) error

LeafDecoder is to be provided (via RegisterLeafDecoder above) by additional wrapper types not yet known to this library. A nil return indicates that decoding was not successful.

type LeafEncoder

type LeafEncoder = func(ctx context.Context, err error) (msg string, safeDetails []string, payload proto.Message)

LeafEncoder is to be provided (via RegisterLeafEncoder above) by additional wrapper types not yet known to this library.

type MessageType

type MessageType errorspb.MessageType

MessageType is used to encode information about an error message within a wrapper error type. This information is used to affect display logic.

const (
	// Prefix denotes an error message that should be prepended to the
	// message of its cause.
	Prefix MessageType = MessageType(errorspb.MessageType_PREFIX)
	// FullMessage denotes an error message that contains the text of its
	// causes and can be displayed standalone.
	FullMessage = MessageType(errorspb.MessageType_FULL_MESSAGE)
)

Values below should match the ones in errorspb.MessageType for direct conversion.

type MultiCauseDecoder

type MultiCauseDecoder = func(ctx context.Context, causes []error, msgPrefix string, safeDetails []string, payload proto.Message) error

MultiCauseDecoder is to be provided (via RegisterMultiCauseDecoder above) by additional multi-cause wrapper types not yet known by the library. A nil return indicates that decoding was not successful.

type MultiCauseEncoder

type MultiCauseEncoder = func(ctx context.Context, err error) (msg string, safeDetails []string, payload proto.Message)

MultiCauseEncoder is to be provided (via RegisterMultiCauseEncoder above) by additional multi-cause wrapper types not yet known to this library. The encoder will automatically extract and encode the causes of this error by calling `Unwrap()` and expecting a slice of errors.

type OpaqueErrno

type OpaqueErrno struct {
	// contains filtered or unexported fields
}

OpaqueErrno represents a syscall.Errno error object that was constructed on a different OS/platform combination.

func (*OpaqueErrno) Error

func (o *OpaqueErrno) Error() string

Error implements the error interface.

func (*OpaqueErrno) Is

func (o *OpaqueErrno) Is(target error) bool

Is tests whether this opaque errno object represents a special os error type.

func (*OpaqueErrno) Temporary

func (o *OpaqueErrno) Temporary() bool

Temporary tests whether this opaque errno object encodes a temporary error.

func (*OpaqueErrno) Timeout

func (o *OpaqueErrno) Timeout() bool

Timeout tests whether this opaque errno object encodes a timeout error.

type Printer

type Printer interface {
	// Print appends args to the message output.
	Print(args ...interface{})

	// Printf writes a formatted string.
	Printf(format string, args ...interface{})

	// Detail reports whether error detail is requested.
	// After the first call to Detail, all text written to the Printer
	// is formatted as additional detail, or ignored when
	// detail has not been requested.
	// If Detail returns false, the caller can avoid printing the detail at all.
	Detail() bool
}

A Printer formats error messages.

The most common implementation of Printer is the one provided by package fmt during Printf (as of Go 1.13). Localization packages such as golang.org/x/text/message typically provide their own implementations.

type SafeDetailPayload

type SafeDetailPayload struct {
	// OriginalTypeName is the concrete type of the error that the details
	// are coming from.
	OriginalTypeName string
	// ErrorTypeMark is the mark of the error that the details are
	// coming from. This may contain a different type name than
	// OriginalTypeName in case an error type was migrated.
	ErrorTypeMark errorspb.ErrorTypeMark
	// SafeDetails are the PII-free strings.
	SafeDetails []string
}

SafeDetailPayload captures the safe strings for one level of wrapping.

func GetAllSafeDetails

func GetAllSafeDetails(err error) []SafeDetailPayload

GetAllSafeDetails collects the safe details from the given error object and all its causes. The details are collected from outermost to innermost level of cause.

func GetSafeDetails

func GetSafeDetails(err error) (payload SafeDetailPayload)

GetSafeDetails collects the safe details from the given error object. If it is a wrapper, only the details from the wrapper are returned.

func (*SafeDetailPayload) Fill

func (s *SafeDetailPayload) Fill(slice []string) []string

Fill can be used to concatenate multiple SafeDetailPayloads.

type SafeDetailer

type SafeDetailer interface {
	SafeDetails() []string
}

SafeDetailer is an interface that can be implemented by errors that can provide PII-free additional strings suitable for reporting or telemetry.

type SafeFormatter

type SafeFormatter interface {
	// SafeFormatError prints the receiver's first error.
	//
	// The provided Printer behaves like a redact.SafePrinter its
	// Print() and Printf() methods conditionally add redaction markers
	// around unsafe bits.
	//
	// The return value of SafeFormatError() decides what happens in the
	// case the method is used to produce a "short" message, eg. when it
	// is used to implement Error():
	//
	// - if it returns nil, then the short message
	//   contains no more than that produced for this error,
	//   even if the error has a further causal chain.
	//
	// - if it returns non-nil, then the short message
	//   contains the value printed by this error,
	//   followed by that of its causal chain.
	//   (e.g. thiserror: itscause: furthercause)
	//
	// Note that all the causal chain is reported in verbose reports in
	// any case.
	SafeFormatError(p Printer) (next error)
}

SafeFormatter is implemented by error leaf or wrapper types that want to separate safe and non-safe information when printed out.

When multiple errors are chained (e.g. via errors.Wrap), intermediate layers in the error that do not implement SafeError are considered “unsafe”

type StackFrame

type StackFrame = pkgErr.Frame

StackFrame is the type of a single call frame entry. This mirrors the type of the same name in github.com/pkg/errors.

type StackTrace

type StackTrace = pkgErr.StackTrace

StackTrace is the type of the data for a call stack. This mirrors the type of the same name in github.com/pkg/errors.

func ElideSharedStackTraceSuffix

func ElideSharedStackTraceSuffix(prevStack, newStack StackTrace) (StackTrace, bool)

ElideSharedStackTraceSuffix removes the suffix of newStack that's already present in prevStack. The function returns true if some entries were elided.

type StackTraceProvider

type StackTraceProvider interface {
	StackTrace() StackTrace
}

StackTraceProvider is a provider of StackTraces. This is, intendedly, defined to be implemented by pkg/errors.stack.

type TypeKey

type TypeKey string

TypeKey identifies an error for the purpose of looking up decoders. It is equivalent to the "family name" in ErrorTypeMarker.

func GetTypeKey

func GetTypeKey(err error) TypeKey

GetTypeKey retrieve the type key for a given error object. This is meant for use in combination with the Register functions.

type TypeKeyMarker

type TypeKeyMarker interface {
	ErrorKeyMarker() string
}

TypeKeyMarker can be implemented by errors that wish to extend their type name as seen by GetTypeKey().

Note: the key marker is considered safe for reporting and is included in sentry reports.

type WrapperDecoder

type WrapperDecoder = func(ctx context.Context, cause error, msgPrefix string, safeDetails []string, payload proto.Message) error

WrapperDecoder is to be provided (via RegisterWrapperDecoder above) by additional wrapper types not yet known to this library. A nil return indicates that decoding was not successful.

type WrapperEncoder

type WrapperEncoder func(ctx context.Context, err error) (
	msgPrefix string,
	safeDetails []string,
	payload proto.Message,
)

WrapperEncoder is to be provided (via RegisterWrapperEncoder above) by additional wrapper types not yet known to this library.

type WrapperEncoderWithMessageType

type WrapperEncoderWithMessageType func(ctx context.Context, err error) (
	msgPrefix string,
	safeDetails []string,
	payload proto.Message,
	messageType MessageType,
)

WrapperEncoderWithMessageType is to be provided (via RegisterWrapperEncoderWithMessageType above) by additional wrapper types not yet known to this library. This encoder returns an additional enum which indicates whether the wrapper owns the error message completely instead of simply being a prefix with the error message of its causes appended to it. This information is encoded along with the prefix in order to provide context during error display.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL