errutil

package
v0.18.7 Latest Latest
Warning

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

Go to latest
Published: May 16, 2025 License: MIT Imports: 0 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func As

func As[T error](err error, target *T) bool

As finds the first error in err's tree that matches target, and if one is found, sets target to that error value and returns true. Otherwise, it returns false.

The tree consists of err itself, followed by the errors obtained by repeatedly calling its Unwrap() error or Unwrap() []error method. When err wraps multiple errors, As examines err followed by a depth-first traversal of its children.

An error matches target if the error's concrete value is assignable to the value pointed to by target or if the error has a method As(any) bool such that As(target) returns true. In the latter case, the As method is responsible for setting target.

An error type might provide an As method so it can be treated as if it were a different error type.

As panics if err is not nil and target is nil.

Example
package main

import (
	"fmt"
	"io/fs"
	"os"

	"github.com/sillen102/simba/errutil"
)

func main() {
	if _, err := os.Open("non-existing"); err != nil {
		var pathError *fs.PathError
		if errutil.As(err, &pathError) {
			fmt.Println("Failed at path:", pathError.Path)
		} else {
			fmt.Println(err)
		}
	}
}
Output:

Failed at path: non-existing
Example (Interface)

In this example, the target's desired type is an interface type other than error:

interface { Timeout() bool }

A simple workaround for coaxing As into accepting such a target simply consists in embedding error in the target's desired type.

package main

import (
	"fmt"
	"net"

	"github.com/sillen102/simba/errutil"
)

func main() {
	fakeLookupIP := func(_ string) ([]net.IP, error) {
		return nil, &net.DNSError{IsTimeout: true}
	}
	if _, err := fakeLookupIP("invalid-TLD.123"); err != nil {
		var to interface {
			Timeout() bool
			error // for errutil.As to accept &to as its second argument
		}
		if errutil.As(err, &to) {
			fmt.Printf("Timed out: %t\n", to.Timeout())
		} else {
			fmt.Println(err)
		}
	}
}
Output:

Timed out: true

func Find

func Find[T error](err error) (T, bool)

Find finds the first error in err's tree that matches type T, and if so, returns the corresponding value and true. Otherwise, it returns the zero value and false.

The tree consists of err itself, followed by the errors obtained by repeatedly calling its Unwrap() error or Unwrap() []error method. When err wraps multiple errors, Find examines err followed by a depth-first traversal of its children.

An error matches type T if type-asserting it to T succeeds, or if the error has a method As(any) bool such that As(target), where target is any non-nil value of type *T, returns true. In the latter case, the As method is responsible for setting target.

An error type might provide an As method so it can be treated as if it were a different error type.

Example
package main

import (
	"fmt"
	"io/fs"
	"os"

	"github.com/sillen102/simba/errutil"
)

func main() {
	if _, err := os.Open("non-existing"); err != nil {
		if pathError, ok := errutil.Find[*fs.PathError](err); ok {
			fmt.Println("Failed at path:", pathError.Path)
		} else {
			fmt.Println(err)
		}
	}
}
Output:

Failed at path: non-existing
Example (Interface)

In this example, the result's desired type is an interface type other than error:

interface { Timeout() bool }

A simple workaround for coaxing Find into accepting such a type argument simply consists in embedding error in the result's desired type.

package main

import (
	"fmt"
	"net"

	"github.com/sillen102/simba/errutil"
)

func main() {
	fakeLookupIP := func(_ string) ([]net.IP, error) {
		return nil, &net.DNSError{IsTimeout: true}
	}
	if _, err := fakeLookupIP("invalid-TLD.123"); err != nil {
		type timeouter interface {
			Timeout() bool
			error // for errutil.Find to accept timeouter as its type argument
		}
		if to, ok := errutil.Find[timeouter](err); ok {
			fmt.Printf("Timed out: %t\n", to.Timeout())
		} else {
			fmt.Println(err)
		}
	}
}
Output:

Timed out: true

Types

This section is empty.

Jump to

Keyboard shortcuts

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