Supposons que j'ai un dict comme :

envs = {
    "prod": "PRODSERVERNAME",
    "test": "TESTSERVERNAME",
    "dev": "DEVSERVERNAME"
}

Et je souhaite modifier le message renvoyé par KeyError, ce que j'ai vu dans les articles Web sur le sujet, c'est d'imprimer le nouveau message, comme :

try:
    server = envs[env]
except KeyError:
    print(
        f'No environment found for "{env}"; env must be one of the following: {", ".join(envs.keys())}'
        )

Il me semble que je voudrais toujours lancer l'erreur appropriée (dans ce cas, KeyError à lancer), juste avec des informations plus utiles/spécifiques sur cette erreur. Avec cette hypothèse (veuillez me corriger s'il existe une meilleure pratique à ce sujet), je mettrais en œuvre cette intention comme :

try:
    server = envs[env]
except KeyError:
    raise KeyError(
        f'No environment found for "{env}"; env must be one of the following: {", ".join(envs.keys())}'
        )

Mais exclure une erreur uniquement pour lancer l'erreur du même type semble au mieux inélégant, et au pire janky.

Ma question est : quelle est la manière appropriée de gérer des situations comme celle-ci ? Y a-t-il une documentation que j'ai peut-être manquée sur les meilleures pratiques liées à ce sujet ?

Merci d'avance.

0
dvp 14 nov. 2020 à 00:14

1 réponse

Meilleure réponse

Je dirais que c'est une question de préférence. Votre code fonctionnera très bien et sera lisible tel quel. C'est juste une question de ce que vous essayez d'accomplir.

Dans ce cas spécifique, vous ne voulez pas vraiment gérer KeyError, mais plutôt lever une exception personnalisée lorsqu'une variable d'environnement est manquante. Alors faites-le.

class CustomException(KeyError):
    def __init__(self, missing, allowed):
        self.value = f"No environment found for {missing}; env must be one of the following: {allowed}"

    def __str__(self):
        return repr(self.value)


server = envs.get(env)
if not server:
    raise CustomException('a', ', '.join(['a', 'b', 'c']))
1
Tom Wojcik 13 nov. 2020 à 21:25