meep: github.com/polydawn/meep Index | Examples | Files | Directories

package meep

import "github.com/polydawn/meep"

More Expressive Error Patterns.

Embed `meep` types in your errors structures to effortlessly get fancy behaviors. Stacks, automatic message generation from your fields, common handling: declaring useful error types is now *much* easier.

Index

Examples

Package Files

common_errors.go damcon.go doc.go meep.go stackinfo.go trait_autodescriber.go trait_causable.go trait_traceable.go traits.go try.go try_handlers.go tryplan.go util.go

func DamageControl Uses

func DamageControl(handle func(error))

Use `DamageControl` for a safe, terse default mechanism to gather panics before they crash your program.

Damage control can be used like this:

defer DamageControl(func(e error) {
	errCh <- e
})

Using damage control in this way at the top of all your goroutines is advised if there's the slightest possibility of panics arising. Typically, pushing the error into a channel handled by the spawning goroutine is a good response.

`DamageControl` uses `recover()` internally. Note that this means you must defer `DamageControl` itself (you cannot defer another func which calls `DamageControl`; `recover` doesn't work like that).

The error type given to the `handle` function will always be `*ErrUnderspecified`. If you have different, more specific error handling paths and types in mind, you should express those by writing your own recovers.

func Meep Uses

func Meep(err error, opts ...Opts) error

func New Uses

func New(err error, opts ...Opts) error

func RecoverPanics Uses

func RecoverPanics(fn func()) (e error)

Invokes your function, captures any panics, and returns them.

This is simply shorthand for writing your own defers/recovers.

Note that RecoverPanics returns `error` rather than `interface{}`. Any values panicked which do not match the `error` interface will be wrapped in the `ErrUntypedPanic` type, with the original value in the `Cause` field.

func Try Uses

func Try(fn func(), plan TryPlan)

Invokes your function, captures any panics, and routes them through the TryPlan.

This may be superior to calling a function that returns an error and calling `TryPlan.MustHandle` yourself, because any panics that *do* occur will retain a stack including their original panic location until the TryPlan evaluates, meaning you can capture it properly with any error with the `meep.TraitTraceable` property.

Code:

meep.Try(func() {
    panic(meep.New(&meep.AllTraits{}))
}, meep.TryPlan{
    {ByType: &meep.ErrInvalidParam{},
        Handler: meep.TryHandlerMapto(&meep.ErrProgrammer{})},
    {ByVal: io.EOF,
        Handler: meep.TryHandlerDiscard},
    {CatchAny: true,
        Handler: func(error) {
            fmt.Println("caught wildcard")
        }},
})

Output:

	caught wildcard

func TryHandlerDiscard Uses

func TryHandlerDiscard(_ error)

type AllTraits Uses

type AllTraits struct {
    TraitTraceable
    TraitCausable
    TraitAutodescribing
}

Bundles all the behaviors for quick and easy use!

type ErrInvalidParam Uses

type ErrInvalidParam struct {
    TraitAutodescribing
    TraitTraceable
    Param  string
    Reason string
}

type ErrNotYetImplemented Uses

type ErrNotYetImplemented struct {
    TraitAutodescribing
    TraitTraceable
}

type ErrProgrammer Uses

type ErrProgrammer struct {
    Msg string
    TraitAutodescribing
    TraitTraceable
    TraitCausable
}

type ErrUnderspecified Uses

type ErrUnderspecified struct {
    TraitAutodescribing
    TraitTraceable
    TraitCausable
}

A default type for grabbag, underspecified errors; it is the type used by `DamageControl` to wrap recovered panics.

type ErrUntypedPanic Uses

type ErrUntypedPanic struct {
    TraitAutodescribing
    TraitTraceable
    Cause interface{}
}

A wrapper for non-error types raised from a panic.

The `Try` system will coerce all non-error types to this automatically.

type Opts Uses

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

func Cause Uses

func Cause(x error) Opts

Use `Cause` to tell `Meep()` that it should attach another error as a cause to the error it's initializating.

Usage:

meep.Meep(
	&ErrSomethingCausable{},
	meep.Cause(fmt.Errorf("the root cause")),
)

func NoStack Uses

func NoStack() Opts

Use `NoStack` to tell `Meep()` that it should skip gathering a stack trace for this error, even if it has `TraitTraceable`.

Usage:

meep.Meep(
	&ErrUsuallyHasAStacktrace{},
	meep.NoStack(), // skip stacks this time.
)

type Stack Uses

type Stack struct {
    Frames []StackFrame
}

func CaptureStack Uses

func CaptureStack() *Stack

Captures a trace of the current stack.

You probably won't want to use this directly; instead, use a `TraitTraceable` like this:

//type ErrXYZ struct { TraitTraceable }
err := meep.New(&ErrXYZ{})
// `err` now automatically has a stack capture!

There's nothing more magical here than `runtime.Callers`; just some additional types and prettyprinting which are absent from stdlib `runtime` because of stdlib's necessary avoidance of invoking complex features in that (zerodep!) package.

type StackFrame Uses

type StackFrame uintptr

func (StackFrame) String Uses

func (pc StackFrame) String() string

`String` returns a human readable form of the frame.

The string includes the path to the file and the linenumber associated with the frame, formatted to match the `file:lineno: ` convention (so your IDE, if it supports that convention, may let you click-to-jump); following the source location info, the function name is suffixed.

func (StackFrame) Where Uses

func (pc StackFrame) Where() (file string, line int, fn string)

type TraitAutodescribing Uses

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

Errors that generate their messages automatically from their fields!

func (*TraitAutodescribing) Error Uses

func (m *TraitAutodescribing) Error() string

Implements `error`.

If you're using other mixins, you may want to override this again; if you're just using `Autodescriber`, it'll do fine.

func (*TraitAutodescribing) ErrorMessage Uses

func (m *TraitAutodescribing) ErrorMessage() string

type TraitCausable Uses

type TraitCausable struct {
    Cause error
}

Errors with other errors as their cause!

type TraitTraceable Uses

type TraitTraceable struct {
    Stack Stack
}

Errors with stacks!

func (TraitTraceable) IsStackSet Uses

func (m TraitTraceable) IsStackSet() bool

func (TraitTraceable) StackString Uses

func (m TraitTraceable) StackString() string

Return the stack of the error formatted as a human readable string: one frame per line. Each line lists the source file, line number, and the name of the function.

func (TraitTraceable) WriteStack Uses

func (m TraitTraceable) WriteStack(w io.Writer)

Same job as StackString; use StackString for convenience, use this for performance.

type TryHandler Uses

type TryHandler func(error)

func TryHandlerMapto Uses

func TryHandlerMapto(toTmpl interface{}) TryHandler

type TryPlan Uses

type TryPlan []TryRoute

TryPlan is a declarative error handling plan.

You can dispatch errors according to several patterns, since both the golang stdlib and many libraries have seen fit to use a variety of different patterns, and they can't easily be distinguished by type alone (e.g. should we typeswitch, or do we need to do actual val/ptr compare):

TryRoute{ByType: exampleVal error,       Handler: fn}
TryRoute{ByVal:  ptrOrVal error,         Handler: fn}
TryRoute{ByFunc: func(error) bool,       Handler: fn}
TryRoute{CatchAny: true,                 Handler: fn}

The `By*` fields are used to check whether an error should be handled by that route; then the handler is called when a route matches. Errors are checked against routes in the order they're listed in your TryPlan.

Use `ByType` as much as you can. Meep's typed error helpers should make typed errors your default coding style.

Use `ByVal` where you have to; `io.EOF` is one you must check by value.

Use `ByFunc` as a last resort -- but if you really have to do something complicated, go for it.

If you want to catch *everything*, set the CatchAny flag. If using CatchAny, be sure to add it last -- since it matches any error, routes after it will never be called.

func (TryPlan) Handle Uses

func (tp TryPlan) Handle(e error) error

Checks the TryPlan for handlers that match the error, and invokes the first one that does.

The return value is nil if we found and called a handler, or the original error if there was no matching handler.

If the error parameter was nil, no handler will be called, and the result will always be nil.

func (TryPlan) MustHandle Uses

func (tp TryPlan) MustHandle(e error)

Like `Handle(e)`, but will panic if the (non-nil) error is not handled.

type TryRoute Uses

type TryRoute struct {
    ByType   interface{}
    ByVal    interface{}
    ByFunc   func(error) bool
    CatchAny bool

    Handler TryHandler
}

A single route, used to compose a TryPlan.

Typical usage is to set a Handler function, and then treat the other fields as if it's a 'union' (that is, only set one of them), like this:

TryRoute{ByVal: io.EOF, Handler: func(e error) { fmt.Println(e) }}

func (TryRoute) Matches Uses

func (tr TryRoute) Matches(e error) bool

Directories

PathSynopsis
fixtures

Package meep imports 7 packages (graph). Updated 2017-10-05. Refresh now. Tools for package owners. This is an inactive package (no imports and no commits in at least two years).