web-dev-qa-db-fra.com

Personnalisé Python Exceptions avec codes d'erreur et messages d'erreur

class AppError(Exception):
    pass

class MissingInputError(AppError):
    pass

class ValidationError(AppError):
    pass

...

def validate(self):
    """ Validate Input and save it """

    params = self.__params

    if 'key' in params:
        self.__validateKey(escape(params['key'][0]))
    else:
        raise MissingInputError

    if 'svc' in params:
        self.__validateService(escape(params['svc'][0]))
    else:
        raise MissingInputError

    if 'dt' in params:
        self.__validateDate(escape(params['dt'][0]))
    else:
        raise MissingInputError


def __validateMulti(self, m):
    """ Validate Multiple Days Request"""

    if m not in Input.__validDays:
        raise ValidationError

    self.__dCast = int(m)

validate () et __validateMulti () sont des méthodes d'une classe qui valident et stockent les paramètres d'entrée transmis. Comme cela est évident dans le code, je lève des exceptions personnalisées lorsque certains paramètres d'entrée sont manquants ou qu'une validation échoue.

J'aimerais définir des codes d'erreur et des messages d'erreur personnalisés spécifiques à mon application, par exemple,

Erreur 1100: "Paramètre clé introuvable. Veuillez vérifier votre saisie."

Erreur 1101: "Paramètre de date introuvable. Veuillez vérifier votre saisie"

...

Erreur 2100: "Le paramètre Plusieurs jours n'est pas valide. Les valeurs acceptées sont 2, 5 et 7."

et signaler la même chose à l'utilisateur.

  1. Comment définir ces codes d'erreur et messages d'erreur dans les exceptions personnalisées?
  2. Comment déclencher/intercepter une exception de manière à savoir quel code/message d'erreur afficher?

(P.S: C'est pour Python 2.4.3).


Bastien Léonard mentionne dans ce SO comment que vous n'avez pas besoin de toujours définir un nouveau __init__ ou __str__; par défaut, les arguments seront placés dans self.args et seront imprimés par __str__.

Ainsi, la solution que je préfère:

class AppError(Exception): pass

class MissingInputError(AppError):

    # define the error codes & messages here
    em = {1101: "Some error here. Please verify.", \
          1102: "Another here. Please verify.", \
          1103: "One more here. Please verify.", \
          1104: "That was idiotic. Please verify."}

Usage:

try:
    # do something here that calls
    # raise MissingInputError(1101)

except MissingInputError, e
    print "%d: %s" % (e.args[0], e.em[e.args[0]])
36
Sam

Voici un exemple rapide d'une classe Exception personnalisée avec des codes spéciaux:

class ErrorWithCode(Exception):
    def __init__(self, code):
        self.code = code
    def __str__(self):
        return repr(self.code)

try:
    raise ErrorWithCode(1000)
except ErrorWithCode as e:
    print("Received error with code:", e.code)

Puisque vous demandiez comment utiliser args voici un exemple supplémentaire ...

class ErrorWithArgs(Exception):
    def __init__(self, *args):
        # *args is used to get a list of the parameters passed in
        self.args = [a for a in args]

try:
    raise ErrorWithArgs(1, "text", "some more text")
except ErrorWithArgs as e:
    print("%d: %s - %s" % (e.args[0], e.args[1], e.args[2]))
64
Bryan

Voici un exemple d'une exception personnalisée que j'ai créée qui utilise des codes d'erreur prédéfinis:

class CustomError(Exception):
"""
Custom Exception
"""

  def __init__(self, error_code, message='', *args, **kwargs):

      # Raise a separate exception in case the error code passed isn't specified in the ErrorCodes enum
      if not isinstance(error_code, ErrorCodes):
          msg = 'Error code passed in the error_code param must be of type {0}'
          raise CustomError(ErrorCodes.ERR_INCORRECT_ERRCODE, msg, ErrorCodes.__class__.__name__)

      # Storing the error code on the exception object
      self.error_code = error_code

      # storing the traceback which provides useful information about where the exception occurred
      self.traceback = sys.exc_info()

      # Prefixing the error code to the exception message
      try:
          msg = '[{0}] {1}'.format(error_code.name, message.format(*args, **kwargs))
      except (IndexError, KeyError):
          msg = '[{0}] {1}'.format(error_code.name, message)

      super().__init__(msg)


# Error codes for all module exceptions
@unique
class ErrorCodes(Enum):
    ERR_INCORRECT_ERRCODE = auto()      # error code passed is not specified in enum ErrorCodes
    ERR_SITUATION_1 = auto()            # description of situation 1
    ERR_SITUATION_2 = auto()            # description of situation 2
    ERR_SITUATION_3 = auto()            # description of situation 3
    ERR_SITUATION_4 = auto()            # description of situation 4
    ERR_SITUATION_5 = auto()            # description of situation 5
    ERR_SITUATION_6 = auto()            # description of situation 6

L'énumération ErrorCodes est utilisée pour définir les codes d'erreur. L'exception est créée de telle manière que le code d'erreur transmis est préfixé au message d'exception.

1