Estou escrevendo um módulo e quero ter uma hierarquia de exceções unificada para as exceções que ele pode gerar (por exemplo, herdar de uma FooError
classe abstrata para todas asfoo
exceções específicas do módulo). Isso permite que os usuários do módulo capturem essas exceções específicas e as tratem distintamente, se necessário. Mas muitas das exceções levantadas no módulo são geradas por causa de alguma outra exceção; por exemplo, falha em alguma tarefa devido a um OSError em um arquivo.
O que eu preciso é "agrupar" a exceção capturada, de modo que ela tenha um tipo e mensagem diferentes , para que as informações estejam disponíveis ainda mais na hierarquia de propagação por qualquer que seja a captura da exceção. Mas não quero perder o tipo, a mensagem e o rastreamento de pilha existentes; todas essas informações são úteis para alguém que tenta depurar o problema. Um manipulador de exceção de nível superior não é bom, pois estou tentando decorar a exceção antes que ela avance na pilha de propagação, e o manipulador de nível superior está muito atrasado.
Isso é parcialmente resolvido derivando os foo
tipos de exceção específicos do meu módulo do tipo existente (por exemplo class FooPermissionError(OSError, FooError)
), mas isso não facilita a quebra da instância de exceção existente em um novo tipo, nem modifica a mensagem.
PEP 3134 do Python "Encadeamento de exceções e rastreamentos incorporados" discute uma alteração aceita no Python 3.0 para "encadear" objetos de exceção, para indicar que uma nova exceção foi gerada durante o tratamento de uma exceção existente.
O que estou tentando fazer está relacionado: preciso também que ele funcione em versões anteriores do Python, e não para encadeamento, mas apenas para polimorfismo. Qual é a maneira certa de fazer isso?
except Exception as e
-> raise type(e), type(e)(e.message + custom_message), sys.exc_info()[2]
-> esta solução é de outra questão SO . Isso não é bonito, mas funcional.