Maison  >  Article  >  développement back-end  >  Introduction détaillée au mécanisme de gestion des erreurs dans Golang

Introduction détaillée au mécanisme de gestion des erreurs dans Golang

王林
王林original
2019-12-07 09:36:532741parcourir

Introduction détaillée au mécanisme de gestion des erreurs dans Golang

Bases

La gestion des erreurs doit faire partie du projet. L'erreur dans Golang est de type interface, comme suit :

type error interface {
	Error() string
}

Toute structure qui implémente la méthode

peut être traitée comme une erreur. Par conséquent, si une erreur peut survenir dans la fonction, vous pouvez renvoyer une erreur à la fin de la valeur de retour, telle que : Error()

func foo() error {
	// ... do something
	return errors.New("foo error")
}

Renvoyer l'erreur directement

Renvoie l'erreur directement, similaire à directement Renvoie une erreur de type chaîne, ou un code d'erreur ou similaire. Des erreurs de type chaîne ont été mentionnées dans la section Notions de base. Le code d'erreur est équivalent au code d'erreur de la programmation Linux et C. Généralement, nous devons le définir nous-mêmes. Par exemple :

package mypkg

type ErrCode int

const (
	ERR1 = 1
	ERR2 = 2
	ERR3 = 3
)

func sub(a, b int) (int, ErrCode) {
	if b < 0 {
		return 0, ERR1
	} else if a < b {
		return 0, Err2
	} else if a < 0 {
		return 0, Err3
	}
	return a - b
}

Ce type d'erreur est simple à écrire, mais il présente deux défauts :

1 Si vous souhaitez utiliser des codes d'erreur dans la couche externe, vous devez l'introduire. package, ce qui est simple. Une référence circulaire se produit.

2. Si le type de code d'erreur renvoyé est modifié en interne dans le package, les modifications correspondantes doivent être apportées partout où le code d'erreur est utilisé en externe, détruisant la fermeture.

Pour le premier défaut, vous pouvez utiliser un package tiers pour stocker spécifiquement les codes d'erreur. Cette méthode mérite d'être discutée. Ne jugez jamais la valeur de la chaîne renvoyée par la méthode Error() pour gérer l'erreur correspondante ! ! !

Renvoyer un type personnalisé d'erreur

Cette méthode peut renvoyer un type personnalisé et effectuer la gestion des erreurs associée en affirmant le type personnalisé. Elle peut contenir plus d'informations ; Exemple de code :

package main

import (
	"errors"
	"fmt"
	"runtime/debug"
)

type MyError struct {
	Inner      error                  // 内粗错误
	Message    string                 // 自定义错误信息
	StackTrace string                 // 堆栈信息
	Misc       map[string]interface{} //其它的一些数据
}

func (myError MyError) Error() string {
	return myError.Message
}

func wrapError(err error, msg string, msgArgs ...interface{}) MyError {
	return MyError{
		Inner:      err,
		Message:    fmt.Sprintf(msg, msgArgs),
		StackTrace: string(debug.Stack()),
		Misc:       make(map[string]interface{}),
	}
}

func Handle(key int) error {
	if key < 0 {
		return wrapError(errors.New("key < 0"), "This is an error test")
	}
	return nil
}

func main() {
	if err := Handle(-1); err != nil {
		if e, ok := err.(MyError); ok {
			fmt.Printf("Inner: %v, Message: %v, StackTrace: %v\n",
				e.Inner, e.Message, e.StackTrace)  // 这里输出对应的数据
		}
	}
}

Cette façon de gérer le problème est plus pratique, mais il peut toujours y avoir des problèmes avec les références circulaires de packages.

Gestion des erreurs qui masque les détails internes

Les deux méthodes ci-dessus peuvent être adaptées à certains scénarios, mais aucune ne peut résoudre le problème des éventuelles dépendances circulaires. À cette fin, nous utilisons le package

pour résoudre le problème et donner un exemple de code. github.com/pkg/errors

func New(message string) error

S'il y a une erreur prête à l'emploi, nous devons la regrouper à nouveau. À ce stade, vous avez le choix entre trois fonctions.

//只附加新的信息
func WithMessage(err error, message string) error
//只附加调用堆栈信息
func WithStack(err error) error
//同时附加堆栈和信息
func Wrap(err error, message string) error

En fait, l'empaquetage ci-dessus est très similaire à l'empaquetage d'exceptions de Java. L'erreur empaquetée est en fait Cause. La cause première de l'erreur mentionnée dans le chapitre précédent est cette Cause. Ainsi, cette bibliothèque de gestion des erreurs nous fournit la fonction Cause afin que nous puissions obtenir la cause la plus fondamentale de l'erreur.

func Cause(err error) error {
	type causer interface {
		Cause() error
	}

	for err != nil {
		cause, ok := err.(causer)
		if !ok {
			break
		}
		err = cause.Cause()
	}
	return err
}

Utilisez une boucle for pour trouver l'erreur la plus fondamentale (niveau inférieur).

Articles et tutoriels connexes recommandés :

tutoriel golang

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn