try...catch en Ruby

Nurudeen Ibrahim 30 enero 2023
  1. Rescate con un mensaje de error genérico en Ruby
  2. Rescate con el mensaje de la excepción en Ruby
  3. Rescatar un tipo específico de excepción en Ruby
try...catch en Ruby

Una excepción es un evento no deseado que ocurre durante la ejecución de un programa. Un ejemplo es un ZeroDivisionError cuando un programa intenta dividir un número por cero. Rescatar una excepción es una forma de manejarla con gracia para que no bloquee el programa.

Una excepción en Ruby suele estar formada por dos cláusulas, begin y rescue. La cláusula begin equivale a try en Python o cualquier otro lenguaje de programación similar, mientras que rescue equivale a catch. A continuación se muestra la sintaxis.

begin
  # do something that might cause an exception
rescue
  # handle the exception here
end

Escribamos un programa simple que calcule el porcentaje de ganancia si se dan los precios de venta y costo del bien.

Códigos de ejemplo:

def profit_percentage(selling_price, cost_price)
  profit = selling_price - cost_price
  "#{(profit.fdiv(cost_price) * 100)}%"
end

puts profit_percentage(30, 20)
puts profit_percentage(30, nil)

Producción :

50.0%
nil can't be coerced into Integer (TypeError)

Como podemos ver en el resultado anterior, la segunda invocación de profit_percentage generó un error porque pasamos nil como cost_price. Ahora vamos a ilustrar diferentes formas en las que podríamos haber rescatado esta excepción.

Rescate con un mensaje de error genérico en Ruby

Rescatar con un mensaje de error genérico no siempre es útil porque no revela la causa raíz de la excepción.

Códigos de ejemplo:

def profit_percentage(selling_price, cost_price)
  begin
    profit = selling_price - cost_price
    "#{(profit.fdiv(cost_price) * 100)}%"
  rescue
    "An unknown error occurred."
  end
end

puts profit_percentage(30, nil)

Producción :

An unknown error occurred.

Rescate con el mensaje de la excepción en Ruby

Este método es útil si no está interesado en el tipo de excepción generada sino solo en el mensaje de error.

Códigos de ejemplo:

def profit_percentage(selling_price, cost_price)
  begin
    profit = selling_price - cost_price
    "#{(profit.fdiv(cost_price) * 100)}%"
  rescue => e
    e
  end
end

puts profit_percentage(30, nil)

Producción :

nil can't be coerced into Integer

Rescatar un tipo específico de excepción en Ruby

Es útil si está interesado en manejar solo un tipo particular de excepción.

Códigos de ejemplo:

def profit_percentage(selling_price, cost_price)
  begin
    profit = selling_price - cost_price
    "#{(profit.fdiv(cost_price) * 100)}%"
  rescue TypeError
    "An argument of invalid type was detected"
  end
end

puts profit_percentage(30, nil)

Producción :

An argument of invalid type was detected

Además, vale la pena mencionar que hay otra cláusula opcional llamada ensure, que podría ser útil en los casos en los que siempre necesite ejecutar algún código, independientemente de si se generó una excepción o no.

Códigos de ejemplo:

def profit_percentage(selling_price, cost_price)
  begin
    profit = selling_price - cost_price
    puts "#{(profit.fdiv(cost_price) * 100)}%"
  rescue => e
    puts e
  ensure
    puts "Done calculating profit %"
  end
end

profit_percentage(30, 20)
profit_percentage(30, nil)

Producción :

50.0%
Done calculating profit %

nil can't be coerced into Integer
Done calculating profit %

Como se muestra en el resultado anterior, el código en la cláusula ensure se activó en ambas invocaciones de profit_percentage. Esta cláusula generalmente se usa cuando es necesario cerrar un archivo después de realizar algunas operaciones de archivo, independientemente de si se produjo una excepción o no.