HETIC-MT-P2021 / framework_project

Year project for MT5
https://drive.google.com/drive/folders/1_r9GoeCJzVe4UrsPs_B-FKCA3Pm8TcWm?usp=sharing
MIT License
4 stars 1 forks source link

[Research] Error/Response Handling #13

Open myouuu opened 3 years ago

myouuu commented 3 years ago

Création d'un système de gestion d'erreurs . S'inspirer de Echo

Akecel commented 3 years ago

https://echo.labstack.com/guide/error-handling/

Para0234 commented 3 years ago

Gestion d'erreurs intégrée dans Go

https://www.digitalocean.com/community/tutorials/handling-errors-in-go https://www.geeksforgeeks.org/fmt-errorf-function-in-golang-with-examples/ https://www.geeksforgeeks.org/errors-new-function-in-golang-with-examples/

Go a, par défaut, un système qui permet de gérer les erreurs.

Il existe deux libraries généralement utilisées pour gérer les erreurs : La library errors et la library par défaut fmt.

Je vais mentionner la library errors, mais gardons en mémoire qu'elle est devenue obsolète.

errors.New permet de créer un message d'erreur qui contiendra un string fixe, qui peut par la suite être affiché via la commande fmt.Println

Quant à fmt.Errorf , il permet de créer un message d'erreur descriptif, contrairement à errors.New

Cela signifie que là où errors.New peut donner uniquement un string qui indique une erreur prédéfinie, fmt.Errorf peut quant à lui être modofié pour contenir des informations supplémentaires.

Par exemple :

Ceci est un message d'erreur via l'usage d'errors.New

if resp.StatusCode != 200 {
      err = errors.New("response status code != 200")
      return
}

Ceci est un message d'erreur via l'usage de fmt.Errorf

if resp.StatusCode != 200 {
      err = fmt.Errorf("response status code: %d", resp.StatusCode)
      return
}

Comme on peut le voir, fmt.Errorf permet d'avoir des erreurs contenant des messages variables (Par exemple, incluant un code d'erreur, ou un message spécifique à l'erreur qui a eu lieu.

C'est pour ça que la library errors est passée obsolète.

Dans le cadre de fonctions pouvant retourner une erreur, Go possède les outils pour gérer ce genre de situation.

En effet, lorsque l'on déclare une fonction, il est possible de déclarer de multiples retours, dans l'ordre dans lequel ils seront return, y compris des "error". Par exemple, nous pouvons déclarer une fonction comme ceci :

func fonction(var string) (string, int, float, int, error) {

Le return devra alors avoir 5 variables retournées, exactement de ce type. On peut par exemple avoir ce return final :

return a, b, c, d, ""

avec a un string b un int c un float d un int et "" sur l'"erreur".

Dans ces cas là, l'appel de la fonction sera :

w, x, y, z, err := fonction(e)

avec w un string x un int y un float z un int et err l'"erreur".

Ensuite, il ne reste qu'à faire un

if err != nil {
    fmt.Println("Une erreur a provoqué l'arrêt:", err)
    return
}

pour pouvoir traiter l'erreur.


Gestion d'erreurs customisées

https://www.digitalocean.com/community/tutorials/creating-custom-errors-in-go https://golangbot.com/custom-errors/

L'usage de cette méthode est utile, mais pas parfaite : Cela créé un message d'erreur que l'utilisateur peut récupérer, mais les données transmissibles sont limitées. Si il est nécessaire de récupérer des informations détaillées, alors ces deux méthodes ne sont pas suffisantes. Dans le cadre du projet, il est nécessaire de créer unn système de récupération et traitement des erreurs propoes à nous, et contenant plus d'informations.

Ainsi, pour répondre à notre demande, plus spécifique, il est nécessaire de mettre en place notre propre système.

Pour ce faire, nous pouvons mettre en place notre propre struct d'erreur.

Par exemple :

type erreur struct {  
    comment    string
    code int
}

permet de créer une structure d'erreur qui peut contenir un code d'erreur précis (code, ici) et un string, qui peut contenir des informations nécessaires (Heure de l'erreur, fonction mise en cause, etc., c'est à la préférence du développeur)

Ensuite, il est nécessaire de créer une fonction qui va traiter l'erreur :

func (e *erreur) Error() string {
    return fmt.Sprintf(e.comment, e.code)
}

Cette fonction va return le code et le commentaire de l'erreur. Ainsi, si on prend une fonction qui a pour but d'ajouter 5 à un nombre positif, on pourra avoir comme exemple cette fonction :

func addfive(base int) (int, error) {
    if base < 0 {
        return 0, &erreur{"Nombre d'origine est négatif! Code d'erreur : ", 10}
    }
    return base + 5, nil
}

Cette fonction ajoute 5 au nombre, et retourne "nil" (donc rien) pour l'erreur.

En revanche, en cas d'erreur, la fonction renvoie un code d'erreur et un commentaire décrivant l'erreur.

Cette fonction peut être utilisée dans le main suivant :

func main() {
    base := -6
    added, err := addfive(base)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("nombre additionné : %d", added)
}

En fonction du nombre "base", le programme retournera soit une erreur et son code associé, soit le nombre + 5.

Dans sa totalité, le programme est le suivant :

package main

import (
    "fmt"
)

type erreur struct {
    comment string
    code    int
}

func (e *erreur) Error() string {
    return fmt.Sprintf(e.comment, e.code)
}

func addfive(base int) (int, error) {
    if base < 0 {
        return 0, &erreur{"Nombre d'origine est négatif! Code d'erreur : ", 10}
    }
    return base + 5, nil
}

func main() {
    base := -6
    added, err := addfive(base)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Printf("nombre additionné : %d", added)
}