← Back to Go Course | Chapter 9: Error Handling | Lesson 3 of 6

errors.Is और errors.As

errors.Is पूछता है 'क्या यह बिल्कुल वही तरह की problem है जो मैं ढूंढ रहा हूं?' जबकि errors.As पूछता है 'क्या मैं इसे उस specific error type में unwrap कर सकता हूं जिसे मुझे handle करना आता है?'
Syntax
go
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

markup
// 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")
	}
}

errors.As for Custom Types

errors.As एक specific concrete type से मेल खाती error ढूंढने के लिए wrap chain को चलता है, और अगर मिले, इसे target pointer में assign करता है ताकि आप इसकी fields access कर सकें।

उदाहरण: errors.As for Custom Types

markup
// 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)
	}
}

Why Not Use ==?

एक बार कोई error fmt.Errorf के %w से wrapped हो जाए, resulting error एक नई value है -- original sentinel के खिलाफ एक साधारण == comparison fail होगा भले ही logically यह 'वही' underlying error है, जो बिल्कुल वह समस्या है जिसे errors.Is हल करता है।

Note: किसी codebase में कहीं भी wrapping शामिल होने पर हमेशा errors.Is/errors.As को प्राथमिकता दें।

उदाहरण: Why Not Use ==?

markup
// 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))
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. किसी wrapped error को sentinel error से == से compare करना, जो fmt.Errorf %w से इसे wrap करने के बाद fail हो जाता है।
  2. errors.Is (एक specific sentinel error value जांचता है) को errors.As (एक specific error type निकालता है) के साथ confuse करना।
  3. यह भूल जाना कि दोनों 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:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.