మాడ్యూల్ పాఠాలు (2/5)
ఇడియోమాటిక్ ఎర్రర్ హ్యాండ్లింగ్
Goలో నిర్వహణ లోపం స్పష్టంగా ఉంది: మినహాయింపులు లేవు, ప్రయత్నించండి/క్యాచ్ లేదు. విఫలమయ్యే ప్రతి ఫంక్షన్ errorని దాని చివరి విలువగా చూపుతుంది మరియు కాలర్ నిర్ణయిస్తారు. ఈ అధ్యాయం లోపాలను పటిష్టంగా ఉత్పత్తి చేయడానికి, ప్రచారం చేయడానికి మరియు తనిఖీ చేయడానికి ఇడియోమాటిక్ నమూనాలను సేకరిస్తుంది.
గోల్డెన్ రూల్
data, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("config %s: %w", path, err)
}నాలుగు సూత్రాలు:
errorఅనేది చివరి రిటర్న్.if err != nilతో వెంటనే తనిఖీ చేయండి.- ప్రచారం చేయడానికి ముందు సందర్భాన్ని జోడించండి (
fmt.Errorf+%wతో). - ఎప్పటికీ విస్మరించవద్దు లోపాన్ని: దాన్ని నిర్వహించండి, లాగ్ చేయండి లేదా తిరిగి ఇవ్వండి.
_ = file.Close() // EXPLICITLY ignored (you know what you're doing)సెంటినల్ లోపాలు
ఒక సెంటినల్ ఎర్రర్ అనేది ఎగుమతి చేయబడిన గ్లోబల్ వేరియబుల్ var ErrXxx = errors.New("...") దీనితో కాలర్ పోల్చవచ్చు:
package store
var ErrNotFound = errors.New("not found")
func Get(key string) (string, error) {
if !exists(key) {
return "", ErrNotFound
}
// ...
}కాలర్ ర్యాప్ చైన్లో నడిచే errors.Is (== కాదు) ఉపయోగిస్తాడు:
v, err := store.Get(k)
if errors.Is(err, store.ErrNotFound) {
// handle 404
}ప్రామాణిక ఉదాహరణలు: io.EOF, sql.ErrNoRows, os.ErrNotExist.
కస్టమ్ టైప్ చేసిన లోపాలు
నిర్మాణాత్మక డేటాను (HTTP కోడ్, చెల్లని ఫీల్డ్ మొదలైనవి) క్యారీ చేయడానికి, ఒక రకాన్ని నిర్వచించండి:
type ValidationError struct {
Field string
Msg string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("%s: %s", e.Field, e.Msg)
}గొలుసు వెంట సురక్షితంగా డౌన్క్యాస్ట్ చేయడానికి కాలర్ **errors.As**ని ఉపయోగిస్తాడు:
var ve *ValidationError
if errors.As(err, &ve) {
fmt.Println("invalid field:", ve.Field)
}errors.As Unwrap() చైన్లో పాస్ చేసిన పాయింటర్కు కేటాయించదగిన లోపాన్ని కనుగొనే వరకు నడుస్తుంది.
%wతో చుట్టడం
fmt.Errorf %w క్రియతో ఒక లోపం ఏర్పడుతుంది, అది అసలైనదాన్ని చుట్టేస్తుంది, దానిని errors.Is/errors.As కోసం భద్రపరుస్తుంది:
if err := db.Query(); err != nil {
return fmt.Errorf("load users: %w", err)
}%w లేకుండా (%v లేదా %sని ఉపయోగించి) మీరు రిచ్ స్ట్రింగ్ను పొందుతారు కానీ పోగొట్టుకోండి గొలుసు: కాలర్ ఇకపై నిర్దిష్ట లోపాలను గుర్తించలేరు.
%w కోసం నియమాలు:
- ఒక్కో
fmt.Errorfకాల్కు ఒకటి మాత్రమే (మల్టీ-ర్యాప్కిerrors.Joinఅవసరం). - ఆర్గ్యుమెంట్ తప్పనిసరిగా
errorఅయి ఉండాలి, స్ట్రింగ్ కాదు. - సందర్భంని జోడించండి, అసలు సందేశాన్ని నకిలీ చేయవద్దు.
// bad: duplicates
return fmt.Errorf("error: %w", err) // "error: file not found"
// good: useful context
return fmt.Errorf("load config %s: %w", path, err)బహుళ లోపాల కోసం errors.Join
గో 1.20 నుండి, errors.Join(errs...) బహుళ లోపాలను మిళితం చేసి errors.Is/As ద్వారా గుర్తించగలిగేలా ఉంచుతుంది:
var errs []error
for _, item := range items {
if err := process(item); err != nil {
errs = append(errs, fmt.Errorf("item %s: %w", item.ID, err))
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}panic ఎప్పుడు ఉపయోగించాలి
ఆశించిన లోపాల కోసం ఎప్పుడూ. కేవలం మూడు సందర్భాలలో:
- కోలుకోలేని బగ్: "జరగని" (
panic("unreachable")) స్థానంలో ఉల్లంఘించిన మార్పులేనిది. - స్వతంత్ర ప్రోగ్రామ్ యొక్క
init()/main()లో విఫలమైన ప్రారంభీకరణ (క్లిష్టమైన కాన్ఫిగర్ లేదు → వేగంగా విఫలమవుతుంది). - లైబ్రరీ API దానిని స్పష్టంగా డాక్యుమెంట్ చేస్తుంది: ఉదా.,
regexp.MustCompile(నమూనా చెల్లనిది అయితే భయాందోళనలకు గురవుతుంది — నమూనా బిల్డ్-టైమ్ స్థిరాంకం అయినందున ఆమోదయోగ్యమైనది).
మిగతావన్నీ error. అప్ ప్రచారం చేయడానికి panicని సత్వరమార్గంగా ఉపయోగించవద్దు: ఇది కూర్పును విచ్ఛిన్నం చేస్తుంది, defer Close()ని దాటవేస్తుంది మరియు కాలర్ను అధిగమించింది.
వ్యాయామాలు
Wrappa l'errore di os.ReadFile con fmt.Errorf usando il verbo %w e aggiungendo il contesto 'config:' (con il path).
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
యుసా ఎర్రర్లు. ఈస్ పర్ వెరిఫికేర్ సె ఎర్ర్ నెల్లా కాటేనా డి ర్యాప్ కోర్రిస్పాండే అల్లా సెంటినెల్లా ఎర్రర్ నాట్ ఫౌండ్ ఇ స్టాంపా 'మంకా!' తాల్ కాసోలో.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
లైబ్రేరియాలో భయాందోళనలకు గురవుతున్నారా?
func F(x int) {
// ??? panic(...)
}