Médio Python

Exceção personalizada com encadeamento

Enunciado

Crie uma exceção personalizada IdadeInvalidaError que herda de Exception. Escreva uma função validar_idade(idade) que lança IdadeInvalidaError se a idade for negativa ou maior que 150, encadeando a causa com raise ... from ... a partir de um ValueError. Capture a exceção e imprima a mensagem e a causa.

Requisitos

  • A exceção IdadeInvalidaError deve herdar de Exception.
  • A função validar_idade deve lançar IdadeInvalidaError para idades fora do intervalo [0, 150].
  • Deve usar raise IdadeInvalidaError(...) from ValueError(...) para encadear.
  • O bloco de captura deve imprimir a mensagem da exceção e a causa (__cause__).

Código inicial

class IdadeInvalidaError(Exception):
    pass

def validar_idade(idade):
    # seu código aqui
    pass

try:
    validar_idade(-5)
except IdadeInvalidaError as e:
    print(f"Erro: {e}")
    print(f"Causa: {e.__cause__}")

Saída esperada

Erro: Idade -5 inválida
Causa: idade não pode ser negativa
Ver dica

Dentro da função, verifique se a idade é negativa ou > 150. Se for, levante ValueError com uma mensagem e use raise IdadeInvalidaError(...) from ....

Mostrar solução
class IdadeInvalidaError(Exception):
    """Exceção lançada quando a idade está fora do intervalo permitido."""
    pass

def validar_idade(idade):
    if idade < 0:
        raise IdadeInvalidaError(f"Idade {idade} inválida") from ValueError("idade não pode ser negativa")
    if idade > 150:
        raise IdadeInvalidaError(f"Idade {idade} inválida") from ValueError("idade não pode ser maior que 150")
    return idade

try:
    validar_idade(-5)
except IdadeInvalidaError as e:
    print(f"Erro: {e}")
    print(f"Causa: {e.__cause__}")

Passo a passo

  1. Definimos IdadeInvalidaError herdando de Exception.
  2. A função validar_idade verifica se idade < 0; se sim, levanta IdadeInvalidaError com mensagem personalizada e encadeia com ValueError usando from.
  3. Faz o mesmo para idade > 150.
  4. Se a idade for válida, retorna a própria idade.
  5. No bloco try, chamamos validar_idade(-5).
  6. O except IdadeInvalidaError captura a exceção e imprime a mensagem e a causa (__cause__).

Por que funciona

O raise ... from ... define o atributo __cause__ da exceção, permitindo rastrear a origem do erro. Isso é útil para depuração e para dar contexto ao usuário. A exceção personalizada comunica claramente o domínio do problema.

Erros comuns

  • Não usar from: o encadeamento não acontece e __cause__ fica None.
  • Herdar de BaseException: deve-se herdar de Exception para não capturar erros de sistema.
  • Esquecer de capturar a exceção personalizada: se capturar Exception, funciona, mas perde a especificidade.

Outra forma de resolver

Poderia usar raise IdadeInvalidaError(...) sem from, mas aí a causa original não é preservada. O encadeamento é especialmente útil quando você quer converter um erro de baixo nível em um erro de domínio.

Saída esperada

Erro: Idade -5 inválida
Causa: idade não pode ser negativa