mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
errors: add examples for custom Is/As matching
Change-Id: Ia92dae13b6a4e9434b29d2ab3f698f6ba87b4b89 Reviewed-on: https://go-review.googlesource.com/c/go/+/713740 Reviewed-by: Damien Neil <dneil@google.com> Reviewed-by: Mark Freeman <markfreeman@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Damien Neil <dneil@google.com>
This commit is contained in:
parent
ec92bc6d63
commit
1903782ade
1 changed files with 113 additions and 0 deletions
|
|
@ -44,6 +44,39 @@ func ExampleNew() {
|
|||
// Output: emit macho dwarf: elf header corrupted
|
||||
}
|
||||
|
||||
func OopsNew() error {
|
||||
return errors.New("an error")
|
||||
}
|
||||
|
||||
var ErrSentinel = errors.New("an error")
|
||||
|
||||
func OopsSentinel() error {
|
||||
return ErrSentinel
|
||||
}
|
||||
|
||||
// Each call to [errors.New] returns an unique instance of the error,
|
||||
// even if the arguments are the same. To match against errors
|
||||
// created by [errors.New], declare a sentinel error and reuse it.
|
||||
func ExampleNew_unique() {
|
||||
err1 := OopsNew()
|
||||
err2 := OopsNew()
|
||||
fmt.Println("Errors using distinct errors.New calls:")
|
||||
fmt.Printf("Is(%q, %q) = %v\n", err1, err2, errors.Is(err1, err2))
|
||||
|
||||
err3 := OopsSentinel()
|
||||
err4 := OopsSentinel()
|
||||
fmt.Println()
|
||||
fmt.Println("Errors using a sentinel error:")
|
||||
fmt.Printf("Is(%q, %q) = %v\n", err3, err4, errors.Is(err3, err4))
|
||||
|
||||
// Output:
|
||||
// Errors using distinct errors.New calls:
|
||||
// Is("an error", "an error") = false
|
||||
//
|
||||
// Errors using a sentinel error:
|
||||
// Is("an error", "an error") = true
|
||||
}
|
||||
|
||||
// The fmt package's Errorf function lets us use the package's formatting
|
||||
// features to create descriptive error messages.
|
||||
func ExampleNew_errorf() {
|
||||
|
|
@ -88,6 +121,29 @@ func ExampleIs() {
|
|||
// file does not exist
|
||||
}
|
||||
|
||||
type MyIsError struct {
|
||||
err string
|
||||
}
|
||||
|
||||
func (e MyIsError) Error() string {
|
||||
return e.err
|
||||
}
|
||||
func (e MyIsError) Is(err error) bool {
|
||||
return err == fs.ErrPermission
|
||||
}
|
||||
|
||||
// Custom errors can implement a method "Is(error) bool" to match other error values,
|
||||
// overriding the default matching of [errors.Is].
|
||||
func ExampleIs_custom_match() {
|
||||
var err error = MyIsError{"an error"}
|
||||
fmt.Println("Error equals fs.ErrPermission:", err == fs.ErrPermission)
|
||||
fmt.Println("Error is fs.ErrPermission:", errors.Is(err, fs.ErrPermission))
|
||||
|
||||
// Output:
|
||||
// Error equals fs.ErrPermission: false
|
||||
// Error is fs.ErrPermission: true
|
||||
}
|
||||
|
||||
func ExampleAs() {
|
||||
if _, err := os.Open("non-existing"); err != nil {
|
||||
var pathError *fs.PathError
|
||||
|
|
@ -114,6 +170,63 @@ func ExampleAsType() {
|
|||
// Failed at path: non-existing
|
||||
}
|
||||
|
||||
type MyAsError struct {
|
||||
err string
|
||||
}
|
||||
|
||||
func (e MyAsError) Error() string {
|
||||
return e.err
|
||||
}
|
||||
func (e MyAsError) As(target any) bool {
|
||||
pe, ok := target.(**fs.PathError)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
*pe = &fs.PathError{
|
||||
Op: "custom",
|
||||
Path: "/",
|
||||
Err: errors.New(e.err),
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Custom errors can implement a method "As(any) bool" to match against other error types,
|
||||
// overriding the default matching of [errors.As].
|
||||
func ExampleAs_custom_match() {
|
||||
var err error = MyAsError{"an error"}
|
||||
fmt.Println("Error:", err)
|
||||
fmt.Printf("TypeOf err: %T\n", err)
|
||||
|
||||
var pathError *fs.PathError
|
||||
ok := errors.As(err, &pathError)
|
||||
fmt.Println("Error as fs.PathError:", ok)
|
||||
fmt.Println("fs.PathError:", pathError)
|
||||
|
||||
// Output:
|
||||
// Error: an error
|
||||
// TypeOf err: errors_test.MyAsError
|
||||
// Error as fs.PathError: true
|
||||
// fs.PathError: custom /: an error
|
||||
}
|
||||
|
||||
// Custom errors can implement a method "As(any) bool" to match against other error types,
|
||||
// overriding the default matching of [errors.AsType].
|
||||
func ExampleAsType_custom_match() {
|
||||
var err error = MyAsError{"an error"}
|
||||
fmt.Println("Error:", err)
|
||||
fmt.Printf("TypeOf err: %T\n", err)
|
||||
|
||||
pathError, ok := errors.AsType[*fs.PathError](err)
|
||||
fmt.Println("Error as fs.PathError:", ok)
|
||||
fmt.Println("fs.PathError:", pathError)
|
||||
|
||||
// Output:
|
||||
// Error: an error
|
||||
// TypeOf err: errors_test.MyAsError
|
||||
// Error as fs.PathError: true
|
||||
// fs.PathError: custom /: an error
|
||||
}
|
||||
|
||||
func ExampleUnwrap() {
|
||||
err1 := errors.New("error1")
|
||||
err2 := fmt.Errorf("error2: [%w]", err1)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue