Lección 23 de 45 · Errores y archivos

raise y excepciones propias

Convierte una regla de tu programa en un error explícito para que el código que llama pueda decidir cómo reaccionar.

Reglas del dominioReglas y señalesErrores con significado
Índice · Lección 23/45
A veces Python no ve ningún problema, pero tu programa sí

Restar 80 a un saldo de 30 es una operación matemática válida: el resultado es -50. Sin embargo, una aplicación bancaria puede tener la regla «no permitas retirar más dinero del disponible».

raise sirve para decir: «desde el punto de vista de este programa, esta situación no es válida».

Evidencia de aprendizaje

Detectar una regla incumplida dentro de una función y señalarla con raise en el punto correcto.

Una regla de negocio necesita una señal, no un valor ambiguo

Podrías devolver None, False o -1 cuando algo no está permitido. El problema es que quien llama a la función debe recordar qué significa ese valor especial.

Expresar el problema de forma explícita
def retirar(saldo, cantidad):
    if cantidad > saldo:
        raise ValueError("Saldo insuficiente")
    return saldo - cantidad

print(retirar(100, 30))

En el caso válido, la función devuelve el nuevo saldo. En el caso inválido, no finge un resultado: lanza una excepción con un mensaje que explica la regla incumplida.

raise corta el camino normal en el punto exacto del problema

El código posterior no se ejecuta
def validar_edad(edad):
    if edad < 0:
        raise ValueError("La edad no puede ser negativa")
    return edad

print(validar_edad(18))

Si la condición del if se cumple, la función termina en ese instante mediante la excepción. No necesitas añadir un else para el camino válido: si no hubo raise, la ejecución continúa.

Quien llama decide si puede recuperarse

Separar la regla de la respuesta al usuario
def retirar(saldo, cantidad):
    if cantidad > saldo:
        raise ValueError("Saldo insuficiente")
    return saldo - cantidad

try:
    print(retirar(30, 80))
except ValueError as error:
    print(error)

La función retirar() se ocupa de proteger la regla. El código exterior decide cómo presentar el problema. Esta separación hace que la misma función pueda reutilizarse en una web, una aplicación de escritorio o una prueba automática.

Escala la señal solo cuando aporta significado

1. Regla

“No puedes retirar más que el saldo.”

2. Señal estándar

raise ValueError(...) expresa que el valor no es aceptable.

3. Tipo propio, solo si hace falta

SaldoInsuficienteError merece existir cuando otros errores requieren respuestas distintas.

Escribe la condición que detecta la regla rota y lanza ValueError. El código exterior ya decide cómo recuperarse.

Salida esperada
Saldo insuficiente
raise.py
La salida aparecerá aquí.

Necesito una pista
  • Compara cantidad con saldo.
  • Dentro del if, usa raise ValueError("Saldo insuficiente").
Ver una solución razonada
def retirar(saldo, cantidad):
    if cantidad > saldo:
        raise ValueError("Saldo insuficiente")
    return saldo - cantidad

try:
    print(retirar(20, 50))
except ValueError as error:
    print(error)
Ampliación: cuándo crear una excepción propia

Si tu aplicación necesita distinguir saldo insuficiente, cuenta bloqueada y límite diario para responder de forma diferente, un tipo como SaldoInsuficienteError puede aportar significado. No hace falta crear una clase nueva para cada raise.

No uses excepciones para decisiones normales

Que una persona elija «salir» de un menú no es excepcional; es una opción normal y se maneja con if. Una excepción encaja mejor cuando una operación no puede cumplir su contrato.

Esta diferencia evita convertir el flujo cotidiano del programa en una cadena de try/except.

La prueba de comprensión es poder explicar quién es responsable de qué

  • La función detecta una condición inválida y usa raise.
  • El código que llama puede capturar la excepción si sabe recuperarse.
  • Una excepción propia se crea por significado, no por decorar el código.
Con esto basta por ahora

Si sabes cuándo preferir raise frente a devolver un valor especial, puedes continuar.