codekingpro/portable-devtools
114k
1// Copyright 2012 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.4 5package errors_test6 7import (8 "errors"9 "fmt"10 "io/fs"11 "os"12 "time"13)14 15// MyError is an error implementation that includes a time and message.16type MyError struct {17 When time.Time18 What string19}20 21func (e MyError) Error() string {22 return fmt.Sprintf("%v: %v", e.When, e.What)23}24 25func oops() error {26 return MyError{27 time.Date(1989, 3, 15, 22, 30, 0, 0, time.UTC),28 "the file system has gone away",29 }30}31 32func Example() {33 if err := oops(); err != nil {34 fmt.Println(err)35 }36 // Output: 1989-03-15 22:30:00 +0000 UTC: the file system has gone away37}38 39func ExampleNew() {40 err := errors.New("emit macho dwarf: elf header corrupted")41 if err != nil {42 fmt.Print(err)43 }44 // Output: emit macho dwarf: elf header corrupted45}46 47func OopsNew() error {48 return errors.New("an error")49}50 51var ErrSentinel = errors.New("an error")52 53func OopsSentinel() error {54 return ErrSentinel55}56 57// Each call to [errors.New] returns an unique instance of the error,58// even if the arguments are the same. To match against errors59// created by [errors.New], declare a sentinel error and reuse it.60func ExampleNew_unique() {61 err1 := OopsNew()62 err2 := OopsNew()63 fmt.Println("Errors using distinct errors.New calls:")64 fmt.Printf("Is(%q, %q) = %v\n", err1, err2, errors.Is(err1, err2))65 66 err3 := OopsSentinel()67 err4 := OopsSentinel()68 fmt.Println()69 fmt.Println("Errors using a sentinel error:")70 fmt.Printf("Is(%q, %q) = %v\n", err3, err4, errors.Is(err3, err4))71 72 // Output:73 // Errors using distinct errors.New calls:74 // Is("an error", "an error") = false75 //76 // Errors using a sentinel error:77 // Is("an error", "an error") = true78}79 80// The fmt package's Errorf function lets us use the package's formatting81// features to create descriptive error messages.82func ExampleNew_errorf() {83 const name, id = "bimmler", 1784 err := fmt.Errorf("user %q (id %d) not found", name, id)85 if err != nil {86 fmt.Print(err)87 }88 // Output: user "bimmler" (id 17) not found89}90 91func ExampleJoin() {92 err1 := errors.New("err1")93 err2 := errors.New("err2")94 err := errors.Join(err1, err2)95 fmt.Println(err)96 if errors.Is(err, err1) {97 fmt.Println("err is err1")98 }99 if errors.Is(err, err2) {100 fmt.Println("err is err2")101 }102 fmt.Println(err.(interface{ Unwrap() []error }).Unwrap())103 // Output:104 // err1105 // err2106 // err is err1107 // err is err2108 // [err1 err2]109}110 111func ExampleIs() {112 if _, err := os.Open("non-existing"); err != nil {113 if errors.Is(err, fs.ErrNotExist) {114 fmt.Println("file does not exist")115 } else {116 fmt.Println(err)117 }118 }119 120 // Output:121 // file does not exist122}123 124type MyIsError struct {125 err string126}127 128func (e MyIsError) Error() string {129 return e.err130}131func (e MyIsError) Is(err error) bool {132 return err == fs.ErrPermission133}134 135// Custom errors can implement a method "Is(error) bool" to match other error values,136// overriding the default matching of [errors.Is].137func ExampleIs_custom_match() {138 var err error = MyIsError{"an error"}139 fmt.Println("Error equals fs.ErrPermission:", err == fs.ErrPermission)140 fmt.Println("Error is fs.ErrPermission:", errors.Is(err, fs.ErrPermission))141 142 // Output:143 // Error equals fs.ErrPermission: false144 // Error is fs.ErrPermission: true145}146 147func ExampleAs() {148 if _, err := os.Open("non-existing"); err != nil {149 var pathError *fs.PathError150 if errors.As(err, &pathError) {151 fmt.Println("Failed at path:", pathError.Path)152 } else {153 fmt.Println(err)154 }155 }156 157 // Output:158 // Failed at path: non-existing159}160 161func ExampleAsType() {162 if _, err := os.Open("non-existing"); err != nil {163 if pathError, ok := errors.AsType[*fs.PathError](err); ok {164 fmt.Println("Failed at path:", pathError.Path)165 } else {166 fmt.Println(err)167 }168 }169 // Output:170 // Failed at path: non-existing171}172 173type MyAsError struct {174 err string175}176 177func (e MyAsError) Error() string {178 return e.err179}180func (e MyAsError) As(target any) bool {181 pe, ok := target.(**fs.PathError)182 if !ok {183 return false184 }185 *pe = &fs.PathError{186 Op: "custom",187 Path: "/",188 Err: errors.New(e.err),189 }190 return true191}192 193// Custom errors can implement a method "As(any) bool" to match against other error types,194// overriding the default matching of [errors.As].195func ExampleAs_custom_match() {196 var err error = MyAsError{"an error"}197 fmt.Println("Error:", err)198 fmt.Printf("TypeOf err: %T\n", err)199 200 var pathError *fs.PathError201 ok := errors.As(err, &pathError)202 fmt.Println("Error as fs.PathError:", ok)203 fmt.Println("fs.PathError:", pathError)204 205 // Output:206 // Error: an error207 // TypeOf err: errors_test.MyAsError208 // Error as fs.PathError: true209 // fs.PathError: custom /: an error210}211 212// Custom errors can implement a method "As(any) bool" to match against other error types,213// overriding the default matching of [errors.AsType].214func ExampleAsType_custom_match() {215 var err error = MyAsError{"an error"}216 fmt.Println("Error:", err)217 fmt.Printf("TypeOf err: %T\n", err)218 219 pathError, ok := errors.AsType[*fs.PathError](err)220 fmt.Println("Error as fs.PathError:", ok)221 fmt.Println("fs.PathError:", pathError)222 223 // Output:224 // Error: an error225 // TypeOf err: errors_test.MyAsError226 // Error as fs.PathError: true227 // fs.PathError: custom /: an error228}229 230func ExampleUnwrap() {231 err1 := errors.New("error1")232 err2 := fmt.Errorf("error2: [%w]", err1)233 fmt.Println(err2)234 fmt.Println(errors.Unwrap(err2))235 // Output:236 // error2: [error1]237 // error1238}239 