errutil

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Dec 18, 2024 License: MIT Imports: 0 Imported by: 0

README

jub0bs/errutil

tag Go Version Go Reference license build codecov goreport

A collection of utility functions for working with Go errors.

Installation

go get github.com/jub0bs/errutil

jub0bs/errutil requires Go 1.23.1 or above.

Documentation

The documentation is available on pkg.go.dev.

Code coverage

coverage

Benchmarks

Here are some results of benchmarks pitting errutil against errors.As:

goos: linux
goarch: amd64
pkg: github.com/jub0bs/errutil
cpu: AMD EPYC 7763 64-Core Processor
                                                                                    │     errors     │                errutil                │
                                                                                    │     sec/op     │    sec/op      vs base                │
AsAgainstErrorsPkg/nil_error,_nil_target-4                                             3.5220n ± 13%   0.7939n ± 58%  -77.46% (p=0.000 n=10)
AsAgainstErrorsPkg/nil_error,_non-nil_target-4                                         3.9450n ± 19%   0.7905n ± 39%  -79.96% (p=0.000 n=10)
AsAgainstErrorsPkg/no_match-4                                                          59.660n ± 15%    6.746n ± 86%  -88.69% (p=0.000 n=10)
AsAgainstErrorsPkg/simple_match-4                                                      71.765n ± 10%    4.199n ± 26%  -94.15% (p=0.000 n=10)
AsAgainstErrorsPkg/aser-4                                                              62.555n ±  8%    9.154n ± 13%  -85.37% (p=0.000 n=10)
AsAgainstErrorsPkg/wrapper_that_wraps_nil_error-4                                      60.700n ± 13%    8.177n ± 32%  -86.53% (p=0.000 n=10)
AsAgainstErrorsPkg/wrapper_that_contains_match-4                                       84.925n ± 14%    9.410n ± 12%  -88.92% (p=0.000 n=10)
AsAgainstErrorsPkg/deeply_nested_wrapper_that_contains_match-4                         113.25n ± 12%    21.67n ±  8%  -80.87% (p=0.000 n=10)
AsAgainstErrorsPkg/wrapper_that_contains_aser-4                                         82.95n ± 74%    15.78n ± 70%  -80.98% (p=0.000 n=10)
AsAgainstErrorsPkg/empty_joiner-4                                                      70.365n ± 25%    7.448n ± 15%  -89.42% (p=0.000 n=10)
AsAgainstErrorsPkg/joiner_that_contains_nil-4                                          61.220n ±  2%    7.865n ± 10%  -87.15% (p=0.000 n=10)
AsAgainstErrorsPkg/joiner_that_contains_nil_and_match-4                                 88.53n ±  1%    10.87n ±  6%  -87.72% (p=0.000 n=10)
AsAgainstErrorsPkg/joiner_that_contains_non-nil_and_match-4                            101.65n ±  1%    17.18n ± 10%  -83.09% (p=0.000 n=10)
AsAgainstErrorsPkg/joiner_that_contains_match_and_non-nil-4                             88.95n ±  1%    12.19n ± 10%  -86.30% (p=0.000 n=10)
AsAgainstErrorsPkg/joiner_that_contains_two_matches-4                                   88.12n ± 15%    11.94n ±  8%  -86.45% (p=0.000 n=10)
AsAgainstErrorsPkg/deeply_nested_joiner_that_contains_non-nil_and_three_matches-4       88.73n ± 14%    12.06n ± 11%  -86.40% (p=0.000 n=10)
AsAgainstErrorsPkg/mix_of_wrappers_and_joiners-4                                       109.60n ±  8%    16.46n ± 15%  -84.98% (p=0.000 n=10)
AsAgainstErrorsPkg/mix_of_wrappers_and_joiners_that_contains_asers-4                    99.48n ±  8%    23.73n ± 15%  -76.15% (p=0.000 n=10)
AsAgainstErrorsPkg/joiner_that_contains_many_false_asers-4                              333.1n ±  3%    138.9n ± 16%  -58.29% (p=0.000 n=10)
FindAgainstErrorsPkg/nil_error,_nil_target-4                                            3.095n ± 30%    3.716n ± 33%  +20.05% (p=0.035 n=10)
FindAgainstErrorsPkg/nil_error,_non-nil_target-4                                        3.993n ± 10%    3.444n ± 28%  -13.75% (p=0.001 n=10)
FindAgainstErrorsPkg/no_match-4                                                       107.050n ±  8%    7.732n ± 11%  -92.78% (p=0.000 n=10)
FindAgainstErrorsPkg/simple_match-4                                                   108.650n ± 15%    5.369n ± 25%  -95.06% (p=0.000 n=10)
FindAgainstErrorsPkg/aser-4                                                            110.45n ±  9%    48.29n ± 13%  -56.28% (p=0.000 n=10)
FindAgainstErrorsPkg/wrapper_that_wraps_nil_error-4                                    104.35n ± 15%    10.47n ± 34%  -89.97% (p=0.000 n=10)
FindAgainstErrorsPkg/wrapper_that_contains_match-4                                     149.75n ± 14%    10.29n ± 19%  -93.13% (p=0.000 n=10)
FindAgainstErrorsPkg/deeply_nested_wrapper_that_contains_match-4                       160.55n ± 10%    17.63n ± 15%  -89.02% (p=0.000 n=10)
FindAgainstErrorsPkg/wrapper_that_contains_aser-4                                      113.80n ±  3%    50.63n ± 11%  -55.51% (p=0.000 n=10)
FindAgainstErrorsPkg/empty_joiner-4                                                    103.50n ±  6%    10.21n ± 15%  -90.14% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_nil-4                                        105.65n ± 13%    10.64n ± 10%  -89.93% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_nil_and_match-4                              139.60n ± 12%    13.81n ±  9%  -90.11% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_non-nil_and_match-4                          157.35n ±  8%    17.79n ± 17%  -88.70% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_match_and_non-nil-4                          135.95n ± 13%    12.89n ± 14%  -90.51% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_two_matches-4                                138.90n ±  8%    13.71n ± 12%  -90.13% (p=0.000 n=10)
FindAgainstErrorsPkg/deeply_nested_joiner_that_contains_non-nil_and_three_matches-4    132.85n ±  5%    11.67n ±  6%  -91.22% (p=0.000 n=10)
FindAgainstErrorsPkg/mix_of_wrappers_and_joiners-4                                     144.85n ± 12%    15.79n ± 15%  -89.10% (p=0.000 n=10)
FindAgainstErrorsPkg/mix_of_wrappers_and_joiners_that_contains_asers-4                 130.35n ±  3%    51.39n ±  8%  -60.58% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_many_false_asers-4                            368.7n ±  4%    178.4n ± 21%  -51.61% (p=0.000 n=10)
geomean                                                                                 76.25n          11.95n        -84.33%

                                                                                    │    errors    │                 errutil                 │
                                                                                    │     B/op     │    B/op     vs base                     │
AsAgainstErrorsPkg/nil_error,_nil_target-4                                            0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/nil_error,_non-nil_target-4                                        0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/no_match-4                                                         0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/simple_match-4                                                     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/aser-4                                                             0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/wrapper_that_wraps_nil_error-4                                     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/wrapper_that_contains_match-4                                      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/deeply_nested_wrapper_that_contains_match-4                        0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/wrapper_that_contains_aser-4                                       0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/empty_joiner-4                                                     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/joiner_that_contains_nil-4                                         0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/joiner_that_contains_nil_and_match-4                               0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/joiner_that_contains_non-nil_and_match-4                           0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/joiner_that_contains_match_and_non-nil-4                           0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/joiner_that_contains_two_matches-4                                 0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/deeply_nested_joiner_that_contains_non-nil_and_three_matches-4     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/mix_of_wrappers_and_joiners-4                                      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/mix_of_wrappers_and_joiners_that_contains_asers-4                  0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/joiner_that_contains_many_false_asers-4                            0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
FindAgainstErrorsPkg/nil_error,_nil_target-4                                          0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
FindAgainstErrorsPkg/nil_error,_non-nil_target-4                                      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
FindAgainstErrorsPkg/no_match-4                                                       16.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/simple_match-4                                                   16.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/aser-4                                                           16.00 ± 0%     16.00 ± 0%         ~ (p=1.000 n=10) ¹
FindAgainstErrorsPkg/wrapper_that_wraps_nil_error-4                                   16.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/wrapper_that_contains_match-4                                    16.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/deeply_nested_wrapper_that_contains_match-4                      16.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/wrapper_that_contains_aser-4                                     16.00 ± 0%     16.00 ± 0%         ~ (p=1.000 n=10) ¹
FindAgainstErrorsPkg/empty_joiner-4                                                   16.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_nil-4                                       16.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_nil_and_match-4                             16.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_non-nil_and_match-4                         16.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_match_and_non-nil-4                         16.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_two_matches-4                               16.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/deeply_nested_joiner_that_contains_non-nil_and_three_matches-4   16.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/mix_of_wrappers_and_joiners-4                                    16.00 ± 0%      0.00 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/mix_of_wrappers_and_joiners_that_contains_asers-4                16.00 ± 0%     16.00 ± 0%         ~ (p=1.000 n=10) ¹
FindAgainstErrorsPkg/joiner_that_contains_many_false_asers-4                          16.00 ± 0%     16.00 ± 0%         ~ (p=1.000 n=10) ¹
geomean                                                                                          ²               ?                       ² ³
¹ all samples are equal
² summaries must be >0 to compute geomean
³ ratios must be >0 to compute geomean

                                                                                    │    errors    │                 errutil                 │
                                                                                    │  allocs/op   │ allocs/op   vs base                     │
AsAgainstErrorsPkg/nil_error,_nil_target-4                                            0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/nil_error,_non-nil_target-4                                        0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/no_match-4                                                         0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/simple_match-4                                                     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/aser-4                                                             0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/wrapper_that_wraps_nil_error-4                                     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/wrapper_that_contains_match-4                                      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/deeply_nested_wrapper_that_contains_match-4                        0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/wrapper_that_contains_aser-4                                       0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/empty_joiner-4                                                     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/joiner_that_contains_nil-4                                         0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/joiner_that_contains_nil_and_match-4                               0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/joiner_that_contains_non-nil_and_match-4                           0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/joiner_that_contains_match_and_non-nil-4                           0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/joiner_that_contains_two_matches-4                                 0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/deeply_nested_joiner_that_contains_non-nil_and_three_matches-4     0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/mix_of_wrappers_and_joiners-4                                      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/mix_of_wrappers_and_joiners_that_contains_asers-4                  0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
AsAgainstErrorsPkg/joiner_that_contains_many_false_asers-4                            0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
FindAgainstErrorsPkg/nil_error,_nil_target-4                                          0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
FindAgainstErrorsPkg/nil_error,_non-nil_target-4                                      0.000 ± 0%     0.000 ± 0%         ~ (p=1.000 n=10) ¹
FindAgainstErrorsPkg/no_match-4                                                       1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/simple_match-4                                                   1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/aser-4                                                           1.000 ± 0%     1.000 ± 0%         ~ (p=1.000 n=10) ¹
FindAgainstErrorsPkg/wrapper_that_wraps_nil_error-4                                   1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/wrapper_that_contains_match-4                                    1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/deeply_nested_wrapper_that_contains_match-4                      1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/wrapper_that_contains_aser-4                                     1.000 ± 0%     1.000 ± 0%         ~ (p=1.000 n=10) ¹
FindAgainstErrorsPkg/empty_joiner-4                                                   1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_nil-4                                       1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_nil_and_match-4                             1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_non-nil_and_match-4                         1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_match_and_non-nil-4                         1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/joiner_that_contains_two_matches-4                               1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/deeply_nested_joiner_that_contains_non-nil_and_three_matches-4   1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/mix_of_wrappers_and_joiners-4                                    1.000 ± 0%     0.000 ± 0%  -100.00% (p=0.000 n=10)
FindAgainstErrorsPkg/mix_of_wrappers_and_joiners_that_contains_asers-4                1.000 ± 0%     1.000 ± 0%         ~ (p=1.000 n=10) ¹
FindAgainstErrorsPkg/joiner_that_contains_many_false_asers-4                          1.000 ± 0%     1.000 ± 0%         ~ (p=1.000 n=10) ¹
geomean                                                                                          ²               ?                       ² ³
¹ all samples are equal
² summaries must be >0 to compute geomean
³ ratios must be >0 to compute geomean

License

All source code is covered by the MIT License.

Documentation

Overview

Package errutil provides utility functions for working with errors.

The advent of errors.As in the standard library predates that of parametric polymorphism (generics) in the language. As a result, errors.As is not as ergonomic, type-safe, or efficient as it ideally could be. Functions As and Find are inspired by several unaccepted proposals (see issues 51945, 56949, and 64771) and aim to address those limitations.

In most cases, As can be used as a drop-in replacement for errors.As.

Find is a more efficient and arguably more ergonomic alternative to As. Incidentally, the error-inspection draft design proposal suggests that errors.As would have been very similar to Find if the Go team had cracked the parametric-polymorphism nut in time for errors.As's inception in the standard library. In many cases, a call to errors.As can advantageously be refactored to a call to Find.

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/jub0bs/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/jub0bs/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/jub0bs/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/jub0bs/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