Todos os erros em Elixir implementam o Comportamento de Exceção. Assim como o Comportamento de Acesso, o Comportamento de Exceção define funções de callback que um módulo precisa implementar para cumprir o contrato de software do comportamento. Depois que um erro é definido, ele tem as seguintes propriedades:
:message.raise/1 e raise/2 para lançar o erro pretendidoO Comportamento de Exceção também especifica dois callbacks: message/1 e exception/1. Se não forem implementados, serão usadas implementações padrão. message/1 transforma a struct de erro em uma mensagem legível quando chamada com raise. exception/1 permite que contexto adicional seja adicionado à mensagem quando ela é chamada com raise/2
Para definir uma exceção a partir de um módulo de erro, usamos a 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
Erros definidos podem ser usados como um erro embutido, com raise/1 ou raise/2.
raise/1 lança um erro específico pelo nome do seu módulo ou, se o argumento for uma string, lança um RuntimeError com a string como mensagem.raise/2 lança um erro específico pelo nome do seu módulo e aceita um argumento de atributos, que é usado para obter o erro com a mensagem apropriada.Enquanto você continua seu trabalho na Instruments of Texas, a implementação em Elixir da calculadora RPN está avançando. Sua equipe gostaria de conseguir lançar erros mais específicos do que os erros genéricos fornecidos pela biblioteca padrão. Você está fazendo algumas pesquisas, mas decidiu implementar dois novos erros que implementam o Exception Behaviour.
Dividir um número por zero produz um resultado indefinido, e a equipe decide que o melhor é representá-lo por meio de um erro.
Implemente o módulo DivisionByZeroError com a mensagem de erro: "division by zero occurred"
raise DivisionByZeroError
# => ** (DivisionByZeroError) division by zero occurred
As calculadoras RPN usam uma pilha para acompanhar os números antes de serem somados. A equipe representa essa pilha com uma lista de números (inteiros e de ponto flutuante), por exemplo: [3, 4.0]. Cada operação precisa de uma quantidade específica de números na pilha para realizar seu cálculo. Quando não há números suficientes na pilha, isso é chamado de erro de underflow da pilha. Implemente a exceção StackUnderflowError, que fornece uma mensagem padrão e um contexto extra opcional
raise StackUnderflowError
# => ** (StackUnderflowError) stack underflow occurred
raise StackUnderflowError, "when dividing"
# => ** (StackUnderflowError) stack underflow occurred, context: when dividing
Implemente a função divide/1, que recebe uma pilha (uma lista de dois números) e:
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
Repare que a ordem da lista está invertida!
Crie sua conta no Exercism para aprender e dominar Elixir com 58 conceitos168 exercícios e mentoria humana de verdade, tudo de graça.