Todos los errores de Elixir implementan el Exception Behaviour. Igual que el Access Behaviour, el Exception Behaviour define funciones de callback que un módulo debe implementar para cumplir el contrato de software del behaviour. Una vez que se define un error, este tiene las siguientes propiedades:
:message.raise/1 y raise/2 para lanzar el error deseadoEl Exception Behaviour también especifica dos callbacks: message/1 y exception/1. Si no se implementan, se usarán las implementaciones por defecto. message/1 transforma el struct de error en un mensaje legible cuando se llama con raise. exception/1 permite añadir contexto adicional al mensaje cuando se llama con raise/2
Para definir una excepción a partir de un módulo de error, usamos la macro defexception:
# Defines a minimal error, with the name `MyError`
defmodule MyError do
defexception message: "error"
end
# Defines an error with a customized exception/1 function
defmodule MyCustomizedError do
defexception message: "custom error"
@impl true
def exception(value) do
case value do
[] ->
%MyCustomizedError{}
_ ->
%MyCustomizedError{message: "Alert: " <> value}
end
end
end
Los errores definidos se pueden usar como un error integrado, con raise/1 o raise/2.
raise/1 lanza un error concreto por el nombre de su módulo o, si el argumento es un string, lanzará un RuntimeError con el string como mensaje.raise/2 lanza un error concreto por el nombre de su módulo y acepta un argumento de atributos que se usa para obtener el error con el mensaje adecuado.Mientras continúas tu trabajo en Instruments of Texas, se están haciendo progresos en la implementación en Elixir de la calculadora RPN. A tu equipo le gustaría poder lanzar errores más específicos que los genéricos que proporciona la biblioteca estándar. Estás investigando un poco, pero has decidido implementar dos errores nuevos que implementan el comportamiento Exception.
Dividir un número entre cero produce un resultado no definido, que el equipo decide que es mejor representar con un error.
Implementa el módulo DivisionByZeroError para que tenga el mensaje de error: "division by zero occurred"
raise DivisionByZeroError
# => ** (DivisionByZeroError) division by zero occurred
Las calculadoras RPN usan una pila para llevar la cuenta de los números antes de sumarlos. El equipo representa esta pila con una lista de números (enteros y de coma flotante), por ejemplo: [3, 4.0]. Cada operación necesita una cantidad concreta de números en la pila para poder realizar su cálculo. Cuando no hay suficientes números en la pila, se habla de un error de subdesbordamiento de pila. Implementa la excepción StackUnderflowError, que proporciona un mensaje por defecto y un contexto adicional opcional
raise StackUnderflowError
# => ** (StackUnderflowError) stack underflow occurred
raise StackUnderflowError, "when dividing"
# => ** (StackUnderflowError) stack underflow occurred, context: when dividing
Implementa la función divide/1, que recibe una pila (una lista de dos números) y:
RPNCalculator.Exception.divide([])
# => ** (StackUnderflowError) stack underflow occurred, context: when dividing
RPNCalculator.Exception.divide([0, 100])
# => ** (DivisionByZeroError) division by zero occurred
RPNCalculator.Exception.divide([4, 16])
# => 4
¡Fíjate en que el orden de la lista está invertido!
Regístrate en Exercism para aprender y dominar Elixir con 58 conceptos168 ejercicios y mentoría humana real, todo gratis.