errors

package module
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Apr 29, 2025 License: MIT Imports: 5 Imported by: 74

README

README

An errors recorder package

This design supplements and implements the errors interface of golang, Used to provide information such as the cause and file location of the error when it occurs, in order to restore the happened scene.

Due to the large amount of data contained in this erroneous design, it is necessary to pay attention to the frequency of calls to avoid affecting system efficiency.

  • Example
package main

import "github.com/gwaylib/errors"

func fn1(a int) error {
    if a == 0 {
        // return a common no data error
        return errors.ErrNoData.As(a)
    }
    // other errors with fault position
    return errors.New("not implements").As(a)
}

func fn2(b int) error {
    // call and set the error position, do nothing if 'fn1' return nil
    return errors.As(fn1(b))
}

func main() {
    err := fn2(2)
    if err != nil {
        // Attention, errors.ErrNoData == err may not necessarily hold, the Equal method should be used
        if !errors.ErrNoData.Equal(err) {
            panic(err)
        }
        fmt.Println(err)
    }
}
  • Analyze errors position information of Error()
Output:
["test",["errors_test.go:90#errors.TestAs"],["errors_test.go:95#errors.TestAs",123,456]]

Decode: 
["error code", ["runtime stack of New"], ["runtime stack of As", "args of As"...]]
the first one is error code, the second is New, the others are As's called.

Error handling suggestions

  • Prioritize handling errors before handling normal logic, where errors are less likely to be ignored and make the program more robust;
  • Unless the internal handling result of the error is specified, the error should be returned to the caller;
  • If there is no need to return to the caller, a log should be recorded instead of discarding the error
  • Normal logic should be avoided from being placed in 'if' as much as possible for easier indentation reading.
// Suggest
rows, err := db.Query(...)
if err != nil{
    return errors.As(err)
}
defer rows.Close()
...

// Unsuggest
rows, err := db.Query(...)
if err == nil{
    defer rows.Close()
    // ...
} else {
    // handle error or not
}

*) Define errors within a small scope, otherwise there is a risk of diffusion

func Get() (err error){
    // Suggest
    rows, err := db.Query(...)
    if err != nil{
        return errors.As(err)
    }
    defer rows.Close()
  
    if err := rows.Scan(...); err != nil{
        // ...
    }
    ...
}

Documentation

Overview

Error recorder with As

recoding one code, and recording the As caller static with caller, argument information for every As func is called.

the data static format like this: ["error code", ["runtime stack of New"], ["runtime stack of As", "args of As"...], ["runtime statick of As"]...] the first one is error code, the second is New, the others are func As been called.

Example

package main

import "github.com/gwaylib/errors"

func fn1(a int) error {
 if a == 1 {
     return errors.ErrNoData.As(a)
 }
 err := errors.New("not implements") // make a error code and record the first stack of caller runtime.
 return err.As(a) // make the second stack of caller runtime
}

func fn2(b int) error {
  return errors.As(fn1(b)) // make the third stack of caller runtime
}

func main() {
  err := fn2(2)
  if err != nil {
      // errors.ErrNoData == err not necessarily true, so use Equal instead.
      if !errors.ErrNoData.Equal(err) {
          panic(err)
      }

      fmt.Println(err)
  }
}

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrNoData = New("data not found")
)

Functions

func Equal

func Equal(err1 error, err2 error) bool

Compare two error are same instances or code are matched.

func Is

func Is(err1 error, err2 error) bool

Alias name of Equal func, compatible with official errors.Is

Types

type ErrData

type ErrData []interface{}

["error code", ["where stack of first caller ", "As args"...], ["where stack of second caller ", "As args"...]...]

type Error

type Error interface {
	// Return the code of make.
	Code() string

	// Implement the error interface of go package
	Error() string
	// Impelment the json marshal interface of go package.
	MarshalJSON() ([]byte, error)

	// Record the stack when call, and return a new error with new stack.
	As(arg ...interface{}) Error
	// Copy the as stack data for output
	Stack() []interface{}

	// Compare to another error
	// It should be established with err1.Code() == err2.Code().
	Equal(err error) bool
}

func As

func As(err error, args ...interface{}) Error

Record a stack of runtime caller and the reason with as. return a new error pointer after called. return nil if err is nil

func New

func New(code string, args ...interface{}) Error

Make a new error with Error type.

func Parse

func Parse(src string) Error

Parse error from serial string, if it's ErrData format, create an Error of this package defined. if src is empty, return a nil Error

func ParseError

func ParseError(err error) Error

Parse Error from a error instance. If the error is the type of interface Error, directly convert to the Error interface of this package. Call Parse(err.Error()) in others.

func Wrap

func Wrap(err error, args ...interface{}) Error

Alias name of 'As'

Jump to

Keyboard shortcuts

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