Control de errores con Try Except#

Como vimos en la sección previa, una función tiene muchas posibilidades de fallar. Una forma de intentar controlar los errores e identificar los posibles problemas es utilizar el comando try y except. Este comando permite que el programa se detenga cuando encuentre un error o que continúe con el programa en caso de que eso sea lo que queramos.

Supongamos, por ejemplo, que nuestro usuario ingresa todos los valores, pero en la fecha de nacimiento comete un error y no escribe un número sino una cadena de caracteres. En ese caso, el programa se detendrá y no podremos continuar. Podemos evitar esto utilizando el comando try y except:

def saludar(nombre, fecha_nacimiento=1990, lugar_de_nacimiento="Colombia"):
    """Saluda a una persona y le dice su edad.
    
    Parámetros
    ----------
    nombre: str
        Nombre de la persona a saludar
    fecha_nacimiento: int
        Año de nacimiento de la persona
    lugar_de_nacimiento: str
        Lugar de nacimiento de la persona
    """
    try:
        edad = 2023 - fecha_nacimiento
        print(f"Hola {nombre.title()}, ¿cómo estás? Tienes {edad} años y naciste en {lugar_de_nacimiento.title()}.")
    except:
        print("No se pudo calcular la edad. Verifica que la fecha de nacimiento ingresada ({fecha_nacimiento}) sea un número.")

Si el usuario ingresara de manera incorrecta su información, este sería el resultado

No se pudo calcular la edad. Verifica que la fecha de nacimiento ingresada ({fecha_nacimiento}) sea un número.

No obstante, usar try y except de esta manera no es la mejor forma de controlar los errores. En el ejemplo anterior, el programa no se detiene, pero tampoco nos dice qué fue lo que falló. Para esto, podemos utilizar el comando raise:

def saludar(nombre, fecha_nacimiento=1990, lugar_de_nacimiento="Colombia"):
    """Saluda a una persona y le dice su edad.
    
    Parámetros
    ----------
    nombre: str
        Nombre de la persona a saludar
    fecha_nacimiento: int
        Año de nacimiento de la persona
    lugar_de_nacimiento: str
        Lugar de nacimiento de la persona
    """
    try:
        edad = 2023 - fecha_nacimiento
        print(f"Hola {nombre.title()}, ¿cómo estás? Tienes {edad} años y naciste en {lugar_de_nacimiento.title()}.")
    except:
        print("No se pudo calcular la edad. Verifica que la fecha de nacimiento ingresada ({fecha_nacimiento}) sea un número.")
        raise

El error se muestra de esta manera:

No se pudo calcular la edad. Verifica que la fecha de nacimiento ingresada ({fecha_nacimiento}) sea un número.
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[4], line 4
      1 nombre = "Juan"
      2 fecha_nacimiento = "marzo de 1980"
----> 4 saludar(nombre, fecha_nacimiento)

Cell In[3], line 14, in saludar(nombre, fecha_nacimiento, lugar_de_nacimiento)
      2 """Saluda a una persona y le dice su edad.
      3 
      4 Parámetros
   (...)
     11     Lugar de nacimiento de la persona
     12 """
     13 try:
---> 14     edad = 2023 - fecha_nacimiento
     15     print(f"Hola {nombre.title()}, ¿cómo estás? Tienes {edad} años y naciste en {lugar_de_nacimiento.title()}.")
     16 except:

TypeError: unsupported operand type(s) for -: 'int' and 'str'

En este caso, el programa se detiene y necesita ejecutarse nuevamente para corregir el error.

Otra opción consiste en identificar específicamente un tipo de error que podemos controlar. Para el ejemplo que hemos usado, el error TypeError es el más adecuado:

def saludar(nombre, fecha_nacimiento=1990, lugar_de_nacimiento="Colombia"):
    """Saluda a una persona y le dice su edad.
    
    Parámetros
    ----------
    nombre: str
        Nombre de la persona a saludar
    fecha_nacimiento: int
        Año de nacimiento de la persona
    lugar_de_nacimiento: str
        Lugar de nacimiento de la persona
    """
    try:
        edad = 2023 - fecha_nacimiento
        print(f"Hola {nombre.title()}, ¿cómo estás? Tienes {edad} años y naciste en {lugar_de_nacimiento.title()}.")
    except TypeError:
        print("No se pudo calcular la edad. Verifica que la fecha de nacimiento ingresada ({fecha_nacimiento}) sea un número.")
        raise

El resultado es idéntico a la primera forma que usamos:

No se pudo calcular la edad. Verifica que la fecha de nacimiento ingresada ({fecha_nacimiento}) sea un número.
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[6], line 4
      1 nombre = "Juan"
      2 fecha_nacimiento = "marzo de 1980"
----> 4 saludar(nombre, fecha_nacimiento)

Cell In[5], line 14, in saludar(nombre, fecha_nacimiento, lugar_de_nacimiento)
      2 """Saluda a una persona y le dice su edad.
      3 
      4 Parámetros
   (...)
     11     Lugar de nacimiento de la persona
     12 """
     13 try:
---> 14     edad = 2023 - fecha_nacimiento
     15     print(f"Hola {nombre.title()}, ¿cómo estás? Tienes {edad} años y naciste en {lugar_de_nacimiento.title()}.")
     16 except TypeError:

TypeError: unsupported operand type(s) for -: 'int' and 'str'

No obstante, con eso nos evitamos que el programa se detenga por otros errores que podrían ser saltados o, al contrario, que continúe con el programa cuando no es lo que queremos.