errval

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 6, 2019 License: MIT Imports: 2 Imported by: 0

README

errval

license widget godoc widget circleci widget

Error value generation helper for Go.

// error provider
package provider

var (
	ErrInvalid    = errval.Type("invalid argument")
	ErrPermission = errval.Type("permission denied")
)

func DoSomething1() error {
	return ErrInvalid.New() // here, generates call stack info
}

func DoSomething2() error {
	_, err := os.Open("/tmp/hogehoge")
	if err != nil {
		return ErrPermission.Wrap(err) // here, generates call stack info
	}
	return nil
}

// error consumer
package consumer

func do1() {
	err := provider.DoSomething1()
	if xerrors.Is(err, provider.ErrInvalid) { // true
		// ...
	}
}

func do2() {
	err := provider.DoSomething2()
	if xerrors.Is(err, provider.ErrPermission) { // true
		// ...
	}
}

Motivation

We often use sentinel errors to represent our errors. To make these error values has functionality of identification, wrapping and stack trace, we need to implement custom error type. (See Go 2 Draft Designs for detals.)

errval package provides the helper to define error values easily.

Basic Design

  • Definition as sentinel errors
  • Identified by errors.Is
  • Provides call stack printing
  • Provides error chain printing
  • Not errors.Wrapper
Definition as sentinel errors

errval provides the function (errval.Type) to define errors. errval is assuming that its return values are package variables and exported like sentinel errors.

var (
	ErrInvalid    = errval.Type("invalid argument")
	ErrPermission = errval.Type("permission denied")
)
Identified by errors.Is

The errors defined by errval.Type must be identified by errors.Is. See Go 2 Draft Designs for details.

if xerrors.Is(err, provider.ErrInvalid) {
	// err is an ErrInvalid
}
Provides call stack printing

You can print call stack if you need to know where error occured. Use fmt.Printf and %+v.

// error occur
return ErrInvalid.New() // here, generates call stack info

// print call stack
if err != nil {
	fmt.Printf("%+v", err)
}
Provides error chain printing

You can print error chain if you need to know why error occured. Use fmt.Printf and %+v.

// error occur
cause := ... // other error
if cause != nil {
	return ErrPermission.Wrap(err) // wrap error cause
}

// print error with cause
if err != nil {
	fmt.Printf("%+v", err)
}
Not errors.Wrapper

errval package does not provide implementation for errors.Wrapper. It means that you cannot identify error cause of error. This is because I think that implementators of error should translate errors into their own errors, not just expose error cause. Errors are also part of API.

If you want to expose error cause as your own error, just use fmt.Errorf and : %w.

return fmt.Errorf("error found: %w", err)

Documentation

Overview

Package errval is error value generation helper.

Example
package main

import (
	"fmt"
	"os"

	"github.com/KoharaKazuya/errval"
	"golang.org/x/xerrors"
)

// error types definition
var (
	ErrInvalid    = errval.Type("invalid argument")
	ErrPermission = errval.Type("permission denied")
)

func main() {
	err1 := doSomething1()
	if xerrors.Is(err1, ErrInvalid) {
		fmt.Println("doSomething1 returns an ErrInvalid error")
	}

	err2 := doSomething2()
	if xerrors.Is(err2, ErrPermission) {
		fmt.Println("doSomething2 returns an ErrPermission error")
	}

}

func doSomething1() error {
	return ErrInvalid.New() // generate error
}

func doSomething2() error {
	_, err := os.Open("/tmp/hogehoge") // ErrNotExist
	if err != nil {
		return ErrPermission.Wrap(err) // generate wrapped error
	}
	return nil
}
Output:

doSomething1 returns an ErrInvalid error
doSomething2 returns an ErrPermission error

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ErrType

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

ErrType presents an error type.

func Type

func Type(msg string) *ErrType

Type creates a new ErrType.

func (*ErrType) Error

func (t *ErrType) Error() string

Error returns an error message string. This implementation is necessary to be able to use as and argument of `errors.Is` .

func (*ErrType) New

func (t *ErrType) New() error

New creates an error of receiver error type.

func (*ErrType) Wrap

func (t *ErrType) Wrap(err error) error

Wrap create an error of receiver error type with error cause.

type ErrVal

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

ErrVal presents an error value. ErrVal must be created as return value of `ErrType.New` or `ErrType.Wrap`.

func (*ErrVal) Error

func (v *ErrVal) Error() string

Error returns an error message string.

func (*ErrVal) Format

func (v *ErrVal) Format(f fmt.State, c rune)

Format prints the stack as error detail.

func (*ErrVal) FormatError

func (v *ErrVal) FormatError(p xerrors.Printer) error

FormatError prints the stack as error detail.

func (*ErrVal) Is

func (v *ErrVal) Is(err error) bool

Is returns a boolean indicating whether the error is a type of given error type.

Jump to

Keyboard shortcuts

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