verror

package
v0.0.0-...-0921c0e Latest Latest
Warning

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

Go to latest
Published: Jun 29, 2017 License: BSD-3-Clause Imports: 11 Imported by: 0

Documentation

Overview

Package verror implements an error reporting mechanism that works across programming environments, and a set of common errors.

Each error has an identifier string, which is used for equality checks. E.g. a Javascript client can check if a Go server returned a NoExist error by checking the string identifier. Error identifier strings start with the VDL package path to ensure uniqueness, e.g. "v.io/v23/verror.NoExist".

Each error contains an action, which is the suggested action for a typical client to perform upon receiving the error. E.g. some action codes represent whether to retry the operation after receiving the error.

Each error also contains a list of typed parameters, and an error message. The error message is created by looking up a format string keyed on the error identifier, and applying the parameters to the format string. This enables error messages to be generated in different languages.

Examples

To define a new error identifier, for example "someNewError", client code is expected to declare a variable like this:

var someNewError = verror.Register("my/package/name.someNewError", NoRetry,
                                   "{1} {2} English text for new error")

Text for other languages can be added to the default i18n Catalogue.

If the error should cause a client to retry, consider replacing "NoRetry" with one of the other Action codes below.

Errors are given parameters when used. Conventionally, the first parameter is the name of the component (typically server or binary name), and the second is the name of the operation (such as an RPC or subcommand) that encountered the error. Other parameters typically identify the object(s) on which the error occurred. This convention is normally applied by New(), which fetches the language, component name and operation name from the context.T:

err = verror.New(someNewError, ctx, "object_on_which_error_occurred")

The ExplicitNew() call can be used to specify these things explicitly:

err = verror.ExplicitNew(someNewError, i18n.GetLangID(ctx),
        "my_component", "op_name", "procedure_name", "object_name")

If the language, component and/or operation name are unknown, use i18n.NoLangID or the empty string, respectively.

Because of the convention for the first two parameters, messages in the catalogue typically look like this (at least for left-to-right languages):

{1} {2} The new error {_}

The tokens {1}, {2}, etc. refer to the first and second positional parameters respectively, while {_} is replaced by the positional parameters not explicitly referred to elsewhere in the message. Thus, given the parameters above, this would lead to the output:

my_component op_name The new error object_name

If a substring is of the form {:<number>}, {<number>:}, {:<number>:}, {:_}, {_:}, or {:_:}, and the corresponding parameters are not the empty string, the parameter is preceded by ": " or followed by ":" or both, respectively. For example, if the format:

{3:} foo {2} bar{:_} ({3})

is used with the cat.Format example above, it yields:

3rd: foo 2nd bar: 1st 4th (3rd)

The Convert() and ExplicitConvert() calls are like New() and ExplicitNew(), but convert existing errors (with their parameters, if applicable) to verror errors with given language, component name, and operation name, if non-empty values for these are provided. They also add a PC to a list of PC values to assist developers hunting for the error.

If the context.T specified with New() or Convert() is nil, a default context is used, set by SetDefaultContext(). This can be used in standalone programmes, or in anciliary threads not associated with an RPC. The user might do the following to get the language from the environment, and the programme name from Args[0]:

ctx := runtime.NewContext()
ctx = i18n.WithLangID(ctx, i18n.LangIDFromEnv())
ctx = verror.WithComponentName(ctx, os.Args[0])
verror.SetDefaultContext(ctx)

A standalone tool might set the operation name to be a subcommand name, if any. If the default context has not been set, the error generated has no language, component and operation values; they will be filled in by the first Convert() call that does have these values.

Index

Constants

This section is empty.

Variables

View Source
var (

	// Unknown means the error has no known Id.  A more specific error should
	// always be used, if possible.  Unknown is typically only used when
	// automatically converting errors that do not contain an Id.
	ErrUnknown = Register("v.io/v23/verror.Unknown", NoRetry, "{1:}{2:} Error{:_}")
	// Internal means an internal error has occurred.  A more specific error
	// should always be used, if possible.
	ErrInternal = Register("v.io/v23/verror.Internal", NoRetry, "{1:}{2:} Internal error{:_}")
	// NotImplemented means that the request type is valid but that the method to
	// handle the request has not been implemented.
	ErrNotImplemented = Register("v.io/v23/verror.NotImplemented", NoRetry, "{1:}{2:} Not implemented{:_}")
	// EndOfFile means the end-of-file has been reached; more generally, no more
	// input data is available.
	ErrEndOfFile = Register("v.io/v23/verror.EndOfFile", NoRetry, "{1:}{2:} End of file{:_}")
	// BadArg means the arguments to an operation are invalid or incorrectly
	// formatted.
	ErrBadArg = Register("v.io/v23/verror.BadArg", NoRetry, "{1:}{2:} Bad argument{:_}")
	// BadState means an operation was attempted on an object while the object was
	// in an incompatible state.
	ErrBadState = Register("v.io/v23/verror.BadState", NoRetry, "{1:}{2:} Invalid state{:_}")
	// BadVersion means the version presented by the client (e.g. to a service
	// that supports content-hash-based caching or atomic read-modify-write) was
	// out of date or otherwise invalid, likely because some other request caused
	// the version at the server to change. The client should get a fresh version
	// and try again.
	ErrBadVersion = Register("v.io/v23/verror.BadVersion", NoRetry, "{1:}{2:} Version is out of date")
	// Exist means that the requested item already exists; typically returned when
	// an attempt to create an item fails because it already exists.
	ErrExist = Register("v.io/v23/verror.Exist", NoRetry, "{1:}{2:} Already exists{:_}")
	// NoExist means that the requested item does not exist; typically returned
	// when an attempt to lookup an item fails because it does not exist.
	ErrNoExist       = Register("v.io/v23/verror.NoExist", NoRetry, "{1:}{2:} Does not exist{:_}")
	ErrUnknownMethod = Register("v.io/v23/verror.UnknownMethod", NoRetry, "{1:}{2:} Method does not exist{:_}")
	ErrUnknownSuffix = Register("v.io/v23/verror.UnknownSuffix", NoRetry, "{1:}{2:} Suffix does not exist{:_}")
	// NoExistOrNoAccess means that either the requested item does not exist, or
	// is inaccessible.  Typically returned when the distinction between existence
	// and inaccessiblity should be hidden to preserve privacy.
	ErrNoExistOrNoAccess = Register("v.io/v23/verror.NoExistOrNoAccess", NoRetry, "{1:}{2:} Does not exist or access denied{:_}")
	// NoServers means a name was resolved to unusable or inaccessible servers.
	ErrNoServers = Register("v.io/v23/verror.NoServers", RetryRefetch, "{1:}{2:} No usable servers found{:_}")
	// NoAccess means the server does not authorize the client for access.
	ErrNoAccess = Register("v.io/v23/verror.NoAccess", RetryRefetch, "{1:}{2:} Access denied{:_}")
	// NotTrusted means the client does not trust the server.
	ErrNotTrusted = Register("v.io/v23/verror.NotTrusted", RetryRefetch, "{1:}{2:} Client does not trust server{:_}")
	// Aborted means that an operation was not completed because it was aborted by
	// the receiver.  A more specific error should be used if it would help the
	// caller decide how to proceed.
	ErrAborted = Register("v.io/v23/verror.Aborted", NoRetry, "{1:}{2:} Aborted{:_}")
	// BadProtocol means that an operation was not completed because of a protocol
	// or codec error.
	ErrBadProtocol = Register("v.io/v23/verror.BadProtocol", NoRetry, "{1:}{2:} Bad protocol or type{:_}")
	// Canceled means that an operation was not completed because it was
	// explicitly cancelled by the caller.
	ErrCanceled = Register("v.io/v23/verror.Canceled", NoRetry, "{1:}{2:} Canceled{:_}")
	// Timeout means that an operation was not completed before the time deadline
	// for the operation.
	ErrTimeout = Register("v.io/v23/verror.Timeout", NoRetry, "{1:}{2:} Timeout{:_}")
)

Functions

func AddSubErrs

func AddSubErrs(err error, ctx *context.T, errors ...SubErr) error

AddSubErrs is like ExplicitAddSubErrs, but uses the provided context to obtain the langID, componentName, and opName values.

func Convert

func Convert(idAction IDAction, ctx *context.T, err error) error

Convert is like ExplicitConvert(), but obtains the language, component and operation names from the specified context.T. ctx may be nil.

func DebugString

func DebugString(err error) string

DebugString returns a more verbose string representation of an error, perhaps more thorough than one might present to an end user, but useful for debugging by a developer.

func ErrorFromNative

func ErrorFromNative(wire **vdl.WireError, native error) error

ErrorFromNative converts from the native to wire representation of errors.

func ErrorToNative

func ErrorToNative(wire *vdl.WireError, native *error) error

ErrorToNative converts from the wire to native representation of errors.

func ExplicitAddSubErrs

func ExplicitAddSubErrs(err error, langID i18n.LangID, componentName string, opName string, errors ...SubErr) error

ExplicitAddSubErrs returns a copy of err with supplied errors appended as subordinate errors. Requires that errors[i].Err!=nil for 0<=i<len(errors).

func ExplicitConvert

func ExplicitConvert(idAction IDAction, langID i18n.LangID, componentName string, opName string, err error) error

ExplicitConvert converts a regular err into an E error, setting its IDAction to idAction. If err is already an E, it returns err or an equivalent value without changing its type, but potentially changing the language, component or operation if langID!=i18n.NoLangID, componentName!="" or opName!="" respectively. The caller's PC is added to the error's stack.

func ExplicitNew

func ExplicitNew(idAction IDAction, langID i18n.LangID, componentName string, opName string, v ...interface{}) error

ExplicitNew returns an error with the given ID, with an error string in the chosen language. The component and operation name are included the first and second parameters of the error. Other parameters are taken from v[]. The parameters are formatted into the message according to i18n.Cat().Format. The caller's PC is added to the error's stack. If the parameter list contains an instance of verror.E, then the stack of the first, and only the first, occurrence of such an instance, will be chained to the stack of this newly created error.

func FromWire

func FromWire(wire *vdl.WireError) error

FromWire is a convenience for generated code to convert wire errors into native errors.

func New

func New(idAction IDAction, ctx *context.T, v ...interface{}) error

New is like ExplicitNew(), but obtains the language, component name, and operation name from the specified context.T. ctx may be nil.

func NewErrAborted

func NewErrAborted(ctx *context.T) error

NewErrAborted returns an error with the ErrAborted ID.

func NewErrBadArg

func NewErrBadArg(ctx *context.T) error

NewErrBadArg returns an error with the ErrBadArg ID.

func NewErrBadProtocol

func NewErrBadProtocol(ctx *context.T) error

NewErrBadProtocol returns an error with the ErrBadProtocol ID.

func NewErrBadState

func NewErrBadState(ctx *context.T) error

NewErrBadState returns an error with the ErrBadState ID.

func NewErrBadVersion

func NewErrBadVersion(ctx *context.T) error

NewErrBadVersion returns an error with the ErrBadVersion ID.

func NewErrCanceled

func NewErrCanceled(ctx *context.T) error

NewErrCanceled returns an error with the ErrCanceled ID.

func NewErrEndOfFile

func NewErrEndOfFile(ctx *context.T) error

NewErrEndOfFile returns an error with the ErrEndOfFile ID.

func NewErrExist

func NewErrExist(ctx *context.T) error

NewErrExist returns an error with the ErrExist ID.

func NewErrInternal

func NewErrInternal(ctx *context.T) error

NewErrInternal returns an error with the ErrInternal ID.

func NewErrNoAccess

func NewErrNoAccess(ctx *context.T) error

NewErrNoAccess returns an error with the ErrNoAccess ID.

func NewErrNoExist

func NewErrNoExist(ctx *context.T) error

NewErrNoExist returns an error with the ErrNoExist ID.

func NewErrNoExistOrNoAccess

func NewErrNoExistOrNoAccess(ctx *context.T) error

NewErrNoExistOrNoAccess returns an error with the ErrNoExistOrNoAccess ID.

func NewErrNoServers

func NewErrNoServers(ctx *context.T) error

NewErrNoServers returns an error with the ErrNoServers ID.

func NewErrNotImplemented

func NewErrNotImplemented(ctx *context.T) error

NewErrNotImplemented returns an error with the ErrNotImplemented ID.

func NewErrNotTrusted

func NewErrNotTrusted(ctx *context.T) error

NewErrNotTrusted returns an error with the ErrNotTrusted ID.

func NewErrTimeout

func NewErrTimeout(ctx *context.T) error

NewErrTimeout returns an error with the ErrTimeout ID.

func NewErrUnknown

func NewErrUnknown(ctx *context.T) error

NewErrUnknown returns an error with the ErrUnknown ID.

func NewErrUnknownMethod

func NewErrUnknownMethod(ctx *context.T) error

NewErrUnknownMethod returns an error with the ErrUnknownMethod ID.

func NewErrUnknownSuffix

func NewErrUnknownSuffix(ctx *context.T) error

NewErrUnknownSuffix returns an error with the ErrUnknownSuffix ID.

func SetDefaultContext

func SetDefaultContext(ctx *context.T)

SetDefaultContext sets the default context used when a nil context.T is passed to New() or Convert(). It is typically used in standalone programmes that have no RPC context, or in servers for the context of ancillary threads not associated with any particular RPC.

func StackToText

func StackToText(w io.Writer, stack []uintptr) error

StackToText emits on w a text representation of stack, which is typically obtained from Stack() and represents the source location(s) where an error was generated or passed through in the local address space.

func VDLRead

func VDLRead(dec vdl.Decoder, x *error) error

VDLRead implements the logic to read x from dec.

Unlike regular VDLRead implementations, this handles the case where the decoder contains a nil value, to make code generation simpler.

func VDLWrite

func VDLWrite(enc vdl.Encoder, x error) error

VDLWrite implements the logic to write x to enc.

Unlike regular VDLWrite implementations, this handles the case where x contains a nil value, to make code generation simpler.

func WireFromNative

func WireFromNative(wire *vdl.WireError, native error) error

WireFromNative converts from the standard go error interface to verror.E, and then to vdl.WireError.

TODO(toddw): Remove this function after the switch to the new vdl Encoder/Decoder is complete.

func WireToNative

func WireToNative(wire vdl.WireError, native *E) error

WireToNative converts from vdl.WireError to verror.E, which implements the standard go error interface.

TODO(toddw): Remove this function after the switch to the new vdl Encoder/Decoder is complete.

func WithComponentName

func WithComponentName(ctx *context.T, componentName string) *context.T

WithComponentName returns a context based on ctx that has the componentName that New() and Convert() can use.

Types

type ActionCode

type ActionCode uint32

An ActionCode represents the action expected to be performed by a typical client receiving an error that perhaps it does not understand.

const (
	// Retry actions are encoded in the bottom few bits.
	RetryActionMask ActionCode = 3

	NoRetry         ActionCode = 0 // Do not retry.
	RetryConnection ActionCode = 1 // Renew high-level connection/context.
	RetryRefetch    ActionCode = 2 // Refetch and retry (e.g., out of date HTTP ETag)
	RetryBackoff    ActionCode = 3 // Backoff and retry a finite number of times.
)

Codes for ActionCode.

func Action

func Action(err error) ActionCode

Action returns the action of the given err, or NoRetry if the err has no Action.

func (ActionCode) RetryAction

func (ac ActionCode) RetryAction() ActionCode

RetryAction returns the part of the ActionCode that indicates retry behaviour.

type E

type E struct {
	ID        ID            // The identity of the error.
	Action    ActionCode    // Default action to take on error.
	Msg       string        // Error message; empty if no language known.
	ParamList []interface{} // The variadic parameters given to ExplicitNew().
	// contains filtered or unexported fields
}

E is the in-memory representation of a verror error.

The wire representation is defined as vdl.WireError; values of E type are automatically converted to/from vdl.WireError by VDL and VOM.

func (E) Error

func (e E) Error() string

Error returns the error message; if it has not been formatted for a specific language, a default message containing the error ID and parameters is generated. This method is required to fulfil the error interface.

func (E) VDLEqual

func (x E) VDLEqual(yiface interface{}) bool

func (*E) VDLRead

func (x *E) VDLRead(dec vdl.Decoder) error

func (E) VDLReflect

func (E) VDLReflect(struct {
	Name string `vdl:"v.io/v23/vdl.WireError"`
})

TypeOf(verror.E{}) should give vdl.WireError.

func (E) VDLWrite

func (x E) VDLWrite(enc vdl.Encoder) error

type ID

type ID string

ID is a unique identifier for errors.

func ErrorID

func ErrorID(err error) ID

ErrorID returns the ID of the given err, or Unknown if the err has no ID. If err is nil then ErrorID returns "".

type IDAction

type IDAction struct {
	ID     ID
	Action ActionCode
}

An IDAction combines a unique identifier ID for errors with an ActionCode. The ID allows stable error checking across different error messages and different address spaces. By convention the format for the identifier is "PKGPATH.NAME" - e.g. ErrIDFoo defined in the "v23/verror" package has id "v23/verror.ErrIDFoo". It is unwise ever to create two IDActions that associate different ActionCodes with the same ID.

func Register

func Register(id ID, action ActionCode, englishText string) IDAction

Register returns a IDAction with the given ID and Action fields, and inserts a message into the default i18n Catalogue in US English. Other languages can be added by adding to the Catalogue.

type PCs

type PCs []uintptr

PCs represents a list of PC locations

func Stack

func Stack(err error) PCs

Stack returns the list of PC locations on the stack when this error was first generated within this address space, or an empty list if err is not an E.

func (PCs) String

func (st PCs) String() string

type SubErr

type SubErr struct {
	Name    string
	Err     error
	Options SubErrOpts
}

A SubErr represents a (string, error, int32) triple, It is the element type for SubErrs.

type SubErrOpts

type SubErrOpts uint32
const (
	// Print, when set in SubErr.Options, tells Error() to print this SubErr.
	Print SubErrOpts = 0x1
)

type SubErrs

type SubErrs []SubErr

A SubErrs is a special type that allows clients to include a list of subordinate errors to an error's parameter list. Clients can add a SubErrs to the parameter list directly, via New() of include one in an existing error using AddSubErrs(). Each element of the slice has a name, an error, and an integer that encodes options such as verror.Print as bits set within it. By convention, clients are expected to use name of the form "X=Y" to distinguish their subordinate errors from those of other abstraction layers. For example, a layer reporting on errors in individual blessings in an RPC might use strings like "blessing=<blessing_name>".

func (SubErrs) String

func (subErrs SubErrs) String() (result string)

String is the default printing function for SubErrs.

Jump to

Keyboard shortcuts

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