errors

package
v0.0.0-...-d125d34 Latest Latest
Warning

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

Go to latest
Published: May 8, 2024 License: Apache-2.0 Imports: 2 Imported by: 0

README

Error Practice in Horizon

Do Not Throw Third Party Error Directly

Before throwing error to its caller, it should be wrapped with more information, such as stack info, error msg and operation. That will help developers localize bugs.

package "github.com/horizoncd/horizon/pkg/gitrepo" 
import (
    "github.com/horizoncd/horizon/pkg/errors"
)
var (
	GitNotFoundErr = errors.New("Not Found")
)
type HorizonGitRepoInterface interface {
}

type HorizonGitRepoInterfaceImp struct {
	GitLabClient *gitlabExternalCall
}


func (h *HorizonGitInterfaceImp) funca(ctx context.Context, file string)(interface{}, error) {
	_, resp, err:= h.GitLabClient.Call(file)
	if resp.StatusCode == http.StatusNotFound {
	  return nil, errors.Wrap(GitNotFoundErr, err.Error())	
    }
	
	return nil, nil
}

Use Errors in Horizon

Horizon defines all errors in a file which you could find it in horizonerrors.go. There are two ways to define a kind of error. First, define an error type, such as

type HorizonErrNotFound struct {
	Source sourceType
}

func NewErrNotFound(source sourceType, msg string) error {
    return errors.Wrap(&HorizonErrNotFound{
        Source: source,
    }, msg)
}

func (e *HorizonErrNotFound) Error() string {
	return fmt.Sprintf("%s not found", e.Source.name)
}

HorizonErrNotFound has a field called Source, it shows which resource leads the error. Horizon decouples error type and resource, for there's many errors in project are associated with resource, if defining an error for every error type and every source, there'll be too much redundancy. Second, for errors not related to resource, Horizon defines errors directly, for example

ErrParamInvalid = errors.New("parameter is invalid")

This is quite simple. Note that, it should be wrapped manually, likes HorizonErrNotFound does in NewErrNotFound

return perror.Wrap(herrors.ErrParamInvalid, "application config for template cannot be empty")

On the above, Horizon uses perror.Wrap(err) getting the underlying error. Correspondingly, there's two ways to handle errors. For error types like HorizonErrNotFound, handling it with

if _, ok := perror.Cause(err).(*herrors.NewErrNotFound); ok {
	...
}

For errors defined directly, handling it like this

if perror.Wrap(err) == herrors.ErrParamInvalid {
	...
}
3. Print Errors

For Horizon wrapped error with stack info and message, in same cases, you don't want to see stack info, and print it like this

func foo() error { 
	return errors.Wrap(sql.ErrNoRows, "foo failed")
}

func bar() error { 
	return errors.WithMessage(foo(), "bar failed")
}

func main() {
	err := bar()
    fmt.Printf("data not found, %v\n", err)
    // Output: 
    // bar failed: foo failed: sql: no rows in result set 
}

Print with stack info

func main() {
    err := bar()
    fmt.Printf("%+v\n", err)
	// Output:
	// sql: no rows in result set
    // foo failed
    // main.foo
    // /usr/three/main.go:11
    // main.bar
    // /usr/three/main.go:15
    // main.main
    // /usr/three/main.go:19
    // runtime.main
    // ... 
}

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Cause

func Cause(err error) error

find the root cause error of the error chain

func Errorf

func Errorf(format string, args ...interface{}) error

Errorf formats according to a format specifier and returns the string as a value that satisfies error. Errorf also records the stack trace at the point it was called. just like fmt.Errorf()

func New

func New(message string) error

New returns an error with the supplied message. New also records the stack trace at the point it was called. just like buildin errors.New()

func WithMessage

func WithMessage(err error, message string) error

WithMessage annotates err with a new message. If err is nil, WithMessage returns nil. extent err with more information but not break the origin error

func WithMessagef

func WithMessagef(err error, format string, args ...interface{}) error

WithMessagef annotates err with the format specifier. extent err with more information but not break the origin error

func WithStack

func WithStack(err error) error

WithStack annotates err with a stack trace at the point WithStack was called. If err is nil, WithStack returns nil.

func Wrap

func Wrap(err error, message string) error

Wrap returns an error annotating err with a stack trace at the point Wrap is called, and the supplied message. If err is nil, Wrap returns nil. always used in the boundary of thirdparty module, do not used thirdparty error directory but define a error (var GitError = errors.New("Git Error")) and Warp with the information of third party error info Wrap(GitError, error.Error())

func Wrapf

func Wrapf(err error, format string, args ...interface{}) error

Wrapf returns an error annotating err with a stack trace at the point Wrapf is called, and the format specifier. If err is nil, Wrapf returns nil.

Types

This section is empty.

Jump to

Keyboard shortcuts

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