Eu geralmente prefiro lidar com exceções internamente (ou seja, tente / exceto dentro da função chamada, possivelmente retornando um Nenhum) porque o python é digitado dinamicamente. Em geral, considero um julgamento de uma forma ou de outra, mas em uma linguagem digitada dinamicamente, existem pequenos fatores que inclinam a balança a favor de não passar a exceção para o chamador:
- Qualquer pessoa que chama sua função não é notificada sobre as exceções que podem ser lançadas. Torna-se uma espécie de arte saber que tipo de exceção você está procurando (e os blocos genéricos, exceto que devem ser evitados).
if val is None
é um pouco mais fácil do que except ComplicatedCustomExceptionThatHadToBeImportedFromSomeNameSpace
. Sério, eu odeio ter que lembrar de digitar from django.core.exceptions import ObjectDoesNotExist
no topo de todos os meus arquivos django apenas para lidar com um caso de uso realmente comum. Em um mundo com tipagem estática, deixe o editor fazer isso por você.
Honestamente, porém, é sempre uma chamada de julgamento, e a situação que você está descrevendo, em que a função chamada recebe um erro que não pode ajudar, é um excelente motivo para levantar novamente uma exceção que seja significativa. Você tem a ideia exata, mas a menos que seja uma exceção, fornecerá informações mais significativas em um rastreamento de pilha do que
AttributeError: 'NoneType' object has no attribute 'foo'
que, nove em dez vezes, é o que o chamador verá se você retornar um Nenhum não atendido, não se preocupe.
(Tudo isso me faz desejar que as exceções python tivessem os cause
atributos por padrão, como em java, o que permite passar exceções em novas exceções para que você possa relançar tudo o que quiser e nunca perder a fonte original do problema.)