errors.Is और errors.As
if errors.Is(err, target) {
// matches target
}
var target *CustomError
if errors.As(err, &target) {
// use target
}
errors.Is for Sentinel Errors
errors.Is जांचता है कि क्या एक target sentinel error किसी error की wrap chain में कहीं भी दिखाई देता है, कई बार wrapped हुए errors को सही से handle करते हुए, एक साधारण == comparison के विपरीत।
उदाहरण: errors.Is for Sentinel Errors
// Every Go file belongs to a package; main builds an executable
package main
// Import the packages this program uses
import (
"errors"
"fmt"
)
var ErrNotFound = errors.New("not found")
// Define the function find
func find(id int) error {
// Check whether id != 1
if id != 1 {
return fmt.Errorf("lookup id %d: %w", id, ErrNotFound)
}
// Send nil back to the caller
return nil
}
// main is where the program starts running
func main() {
// Short declaration: create err and infer the type
err := find(2)
// Check whether errors.Is(err, ErrNotFound)
if errors.Is(err, ErrNotFound) {
fmt.Println("item was not found")
}
}
Login to try C/C++/Java/PHP code in the editor
errors.As for Custom Types
errors.As एक specific concrete type से मेल खाती error ढूंढने के लिए wrap chain को चलता है, और अगर मिले, इसे target pointer में assign करता है ताकि आप इसकी fields access कर सकें।
उदाहरण: errors.As for Custom Types
// Every Go file belongs to a package; main builds an executable
package main
// Import the packages this program uses
import (
"errors"
"fmt"
)
// Define a struct type named RangeError
type RangeError struct {
Value int
}
// Define the method Error on type RangeError
func (e *RangeError) Error() string {
// Sprintf builds a formatted string instead of printing it
return fmt.Sprintf("value %d out of range", e.Value)
}
// Define the function validate
func validate(n int) error {
// Check whether n > 100
if n > 100 {
return fmt.Errorf("validate: %w", &RangeError{Value: n})
}
// Send nil back to the caller
return nil
}
func main() {
err := validate(150)
var rangeErr *RangeError
if errors.As(err, &rangeErr) {
fmt.Println("bad value was:", rangeErr.Value)
}
}
Login to try C/C++/Java/PHP code in the editor
Why Not Use ==?
एक बार कोई error fmt.Errorf के %w से wrapped हो जाए, resulting error एक नई value है -- original sentinel के खिलाफ एक साधारण == comparison fail होगा भले ही logically यह 'वही' underlying error है, जो बिल्कुल वह समस्या है जिसे errors.Is हल करता है।
उदाहरण: Why Not Use ==?
// Every Go file belongs to a package; main builds an executable
package main
// Import the packages this program uses
import (
"errors"
"fmt"
)
var ErrDenied = errors.New("access denied")
// main is where the program starts running
func main() {
// Short declaration: create wrapped and infer the type
wrapped := fmt.Errorf("request failed: %w", ErrDenied)
// Print the values followed by a newline
fmt.Println("== comparison:", wrapped == ErrDenied)
// Print the values followed by a newline
fmt.Println("errors.Is:", errors.Is(wrapped, ErrDenied))
}
Login to try C/C++/Java/PHP code in the editor
- किसी wrapped error को sentinel error से == से compare करना, जो fmt.Errorf %w से इसे wrap करने के बाद fail हो जाता है।
- errors.Is (एक specific sentinel error value जांचता है) को errors.As (एक specific error type निकालता है) के साथ confuse करना।
- यह भूल जाना कि दोनों functions wrapped errors की पूरी chain चलते हैं, सिर्फ सबसे बाहरी नहीं।
- errors.Is जांचता है कि कोई error chain एक specific sentinel error value रखती है या नहीं।
- errors.As जांचता है कि कोई error chain एक specific error type की value रखती है या नहीं और इसे निकालता है।
- दोनों functions fmt.Errorf के %w verb से बने किसी भी wrapped error को अपने आप चलते हैं।
- जब भी errors wrapped हो सकते हों सीधे == comparisons पर errors.Is/errors.As को प्राथमिकता दें।
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: