Qu'est ce qu'un bon design pour un ensemble de classes d'exception? Je vois toutes sortes de choses autour de quelles classes d'exception qui devrait et ne devrait pas le faire, mais pas une conception simple qui est facile à utiliser et à étendre qui fait ces choses.
- Les classes d'exception ne devrait pas lancer des exceptions, car cela pourrait l'amener tout droit à la résiliation du processus sans aucune possibilité d'enregistrer l'erreur etc.
- Il doit être possible d'obtenir une interface utilisateur conviviale de la chaîne, de préférence localisée à leur langue, de sorte qu'il ya quelque chose à leur dire avant de fermer l'application elle-même si elle ne peut pas récupérer d'une erreur.
- Il doit être possible d'ajouter des informations comme la pile se déroule, par exemple, si un analyseur xml ne parvient pas à analyser un flux d'entrée, pour être en mesure d'ajouter que la source était à partir d'un fichier, ou sur le réseau, etc.
- Les gestionnaires d'Exception besoin d'accéder facilement à l'information dont ils ont besoin pour gérer l'exception
- Écrire formaté à l'exception des informations dans un fichier journal (En anglais, pas de traduction ici).
1 et 4, de travailler ensemble est le plus gros problème que je vais avoir, depuis la mise en forme et de sortie de fichier méthodes pourraient éventuellement échouer.
EDIT: Donc, après avoir regardé des classes d'exception en plusieurs classes, et aussi dans la question Neil liés à, il semble être de pratique courante, à juste complètement ignorer le point 1 (et donc le coup de pouce prestations de conseil), ce qui semble être une assez mauvaise idée de moi.
De toute façon j'ai pensé id de poste de la classe d'exception, je suis en train de penser à l'aide.
class Exception : public std::exception
{
public:
//enum for each exception type, which can also be used to determin
//exception class, useful for logging or other localisation methods
//for generating a message of some sort.
enum ExceptionType
{
//shouldnt ever be thrown
UNKNOWN_EXCEPTION = 0,
//same as above but has a string that may provide some info
UNKNOWN_EXCEPTION_STR,
//eg file not found
FILE_OPEN_ERROR,
//lexical cast type error
TYPE_PARSE_ERROR,
//NOTE: in many cases functions only check and throw this in debug
INVALID_ARG,
//an error occured while trying to parse data from a file
FILE_PARSE_ERROR,
}
virtual ExceptionType getExceptionType()const throw()
{
return UNKNOWN_EXCEPTION;
}
virtual const char* what()throw(){return "UNKNOWN_EXCEPTION";}
};
class FileOpenError : public Exception
{
public:
enum Reason
{
FILE_NOT_FOUND,
LOCKED,
DOES_NOT_EXIST,
ACCESS_DENIED
};
FileOpenError(Reason reason, const char *file, const char *dir)throw();
Reason getReason()const throw();
const char* getFile()const throw();
const char* getDir ()const throw();
private:
Reason reason;
static const unsigned FILE_LEN = 256;
static const unsigned DIR_LEN = 256;
char file[FILE_LEN], dir[DIR_LEN];
};
Le Point 1 est réglé, étant donné que toutes les chaînes sont gérées par la copie d'un interne, fixe la taille de la mémoire tampon (troncature si nécessaire, mais toujours une valeur null).
Bien que cela n'a pas d'adresse point 3, mais je pense que le point est plus que probable de l'utilisation limitée dans le monde réel, de toute façon, et ils sont les plus susceptibles d'être abordés en lançant une nouvelle exception en cas de besoin.