Não consigo encontrar muitas informações sobre classes de exceção personalizadas.
O que eu sei
Você pode declarar sua classe de erro personalizada e deixá-la herdar de StandardError
, para que possa ser rescue
d:
class MyCustomError < StandardError
end
Isso permite que você aumente usando:
raise MyCustomError, "A message"
e mais tarde, receba essa mensagem ao resgatar
rescue MyCustomError => e
puts e.message # => "A message"
O que eu não sei
Eu quero dar à minha exceção alguns campos personalizados, mas quero herdar o message
atributo da classe pai. Descobri lendo sobre este tópico que @message
não é uma variável de instância da classe de exceção, então estou preocupado que minha herança não funcione.
Alguém pode me dar mais detalhes sobre isso? Como eu implementaria uma classe de erro personalizada com um object
atributo? O seguinte está correto:
class MyCustomError < StandardError
attr_reader :object
def initialize(message, object)
super(message)
@object = object
end
end
E depois:
raise MyCustomError.new(anObject), "A message"
para obter:
rescue MyCustomError => e
puts e.message # => "A message"
puts e.object # => anObject
vai funcionar e, se funcionar, é esta a maneira correta de fazer as coisas?
rescue Exception => e
. É mais amplo do que o padrãorescue => e
que se estende deStandardError
e captura tudo, incluindo Ctrl + C. Eu fariarescue MyCustomError => e
.Respostas:
raise
já define a mensagem para que você não precise passá-la para o construtor:Eu substituí
rescue Exception
comrescue MyCustomError
, veja Por que é um estilo ruim `resgatar Exception => e` em Ruby? .fonte
rescue Exception
, mas por que nãorescue MyCustomError
?raise MyCustomError, "a message"
semnew
, "uma mensagem" não será definida.Dado o que a documentação do núcleo ruby
Exception
, da qual todos os outros erros herdam, afirma sobre#message
http://ruby-doc.org/core-1.9.3/Exception.html#method-i-message
Eu optaria por redefinir
to_s
/to_str
ou o inicializador. Aqui está um exemplo em que queremos saber, de uma forma legível principalmente por humanos, quando um serviço externo falhou ao fazer algo.NOTA: A segunda estratégia abaixo usa os métodos de string do Rails, como
demodualize
, que pode ser um pouco complicado e, portanto, potencialmente imprudente de fazer em uma exceção. Você também pode adicionar mais argumentos à assinatura do método, se necessário.Substituindo #to_s Strategy e não #to_str, funciona de maneira diferente
Saída do console
Substituindo #initialize Estratégia
Esta é a estratégia mais próxima das implementações que usei em rails. Como observado acima, que utiliza as
demodualize
,underscore
ehumanize
ActiveSupport
métodos. Mas isso poderia ser facilmente removido, como na estratégia anterior.Saída do console
Ferramenta de demonstração
Esta é uma demonstração para mostrar o resgate e a transmissão de mensagens da implementação acima. A classe que levanta as exceções é uma API falsa para Cloudinary. Basta despejar uma das estratégias acima em seu console Rails, seguido por isso.
fonte
Sua ideia está certa, mas a forma como você a chama está errada. Deveria ser
fonte
raise
palavra - chave ou algo assim.initialize
para tomar dois argumentos.new
passa os argumentos parainitialize
.raise(BillRowError.new(:roamingcalls, @index), "Roaming Calls field missing")
. Então ele chamaraise
com dois parâmetros: um novoBillRowError
objeto e sua mensagem. Estou apenas confuso com a sintaxe ... Em outros tutoriais eu sempre vejo assim:raise Error, message
raise
; isso é muito flexível. O problema é que você definiuinitialize
levar dois argumentos e deu apenas um. Veja no seu exemplo.BillRowError.new(:roamingcalls, @index)
recebe dois argumentos.Eu queria fazer algo semelhante. Eu queria passar um objeto para #new e ter a mensagem definida com base em algum processamento do objeto passado. O seguinte funciona.
Observe que, se você não declarar
attr_accessor :message
, não funcionará. Ao resolver o problema do OP, você também pode passar a mensagem como um argumento adicional e armazenar o que quiser. A parte crucial parece substituir #message.fonte