Excepciones
Las excepciones nos permiten interrumpir el flujo normal del programa para indicar que algo inesperado ha sucedido.
Seguramente ya has visto excepciones como SyntaxError que se dispara cuando tienes un error de sintaxis en el código o NoMethodError cuando intentas invocar un método que no existe.
Cuando se dispara una excepción el programa interrumpe el código y termina a menos de que alguien intercepte la excepción y la maneje.

Interceptando excepciones

1
begin
2
1 / 0 # esto lanza una excepción ZeroDivisionError
3
rescue
4
# este código se ejecuta cuando ocurre una excepción
5
end
Copied!
Si queremos ver el mensaje y el stacktrace podemos asignar la excepción a una variable:
1
begin
2
1 / 0
3
rescue => e
4
puts e.message # imprime el mensaje
5
puts e.backtrace.join(`\n`) # imprime el stacktrace
6
end
Copied!
Si queremos interceptar solo unas excepciones específicas debemos escribir el nombre de la clase:
1
begin
2
1 / 0
3
rescue ZeroDivisionError => e
4
# código que se ejecuta cuando ocurre un ZeroDivisionError
5
end
Copied!

Lanzando excepciones

Para lanzar una excepción utiliza la palabra clave raise:
1
raise ArgumentError.new("El argumento es inválido")
Copied!
Cuando se lanza una excepción debemos decidir qué excepción vamos a lanzar. ArgumentError se utiliza cuando existe un error en un argumento de un método. Otra más común es RuntimeError:
1
raise RuntimeError.new("No se esperaba que ...")
Copied!
Otras formas equivalentes en las que puedes lanzar una excepción son:
1
raise RuntimeError, "No se esperaba que ..."
2
3
# lo siguiente genera un RuntimeError
4
raise "No se esperaba que ..."
Copied!
Existen muchas más excepciones incluidas con Ruby y están organizadas en una jerarquía de clases. Veamos algunas de ellas:
1
Exception
2
NoMemoryError
3
ScriptError
4
LoadError
5
NotImplementedError
6
SyntaxError
7
SignalException
8
Interrupt
9
StandardError
10
ArgumentError
11
IOError
12
EOFError
13
IndexError
14
LocalJumpError
15
NameError
16
NoMethodError
17
RangeError
18
FloatDomainError
19
RegexpError
20
RuntimeError
21
SecurityError
22
SystemCallError
23
SystemStackError
24
ThreadError
25
TypeError
26
ZeroDivisionError
27
SystemExit
Copied!
La jerarquía es importante porque cuando capturas, por ejemplo, StandardError, estás capturando cualquier excepción debajo en la jerarquía como ArgumentError, IOError, etc.
En general, uno debe ser lo más específico al capturar excepciones. Evita capturar Exception, es una mala práctica.
Cuando omites la excepción en el rescue realmente estás capturando StandardError (y por lo tanto, cualquier excepción que esté debajo en la jerarquía).

Creando nuestras propias excepciones

También es posible crear nuestras propias excepciones, simplemente crea una clase que extienda de StandardError:
1
class PermissionDeniedError < StandardError
2
end
3
4
raise PermissionDeniedError.new()
Copied!
Como una excepción no es más que una clase normal de Ruby, puedes agregarle un constructor, atributos y métodos:
1
class PermissionDeniedError < StandardError
2
attr_reader :action
3
4
def initialize(message, action)
5
# Call the parent's constructor to set the message
6
super(message)
7
8
# Store the action in an instance variable
9
@action = action
10
end
11
end
12
13
# Cuando alguien trate de borrar algo sin permiso podrías
14
# hacer algo así:
15
raise PermissionDeniedError.new("Permission Denied", :delete)
Copied!
Last modified 3yr ago