Parece que no puedo encontrar mucha información sobre las clases de excepción personalizadas.
Lo que yo se
Puede declarar su clase de error personalizada y dejar que herede StandardError
, por lo que puede ser rescue
d:
class MyCustomError < StandardError
end
Esto te permite aumentarlo usando:
raise MyCustomError, "A message"
y luego, recibe ese mensaje al rescatar
rescue MyCustomError => e
puts e.message # => "A message"
Lo que no se
Quiero darle a mi excepción algunos campos personalizados, pero quiero heredar el message
atributo de la clase principal. Descubrí al leer sobre este tema que @message
no es una variable de instancia de la clase de excepción, por lo que me preocupa que mi herencia no funcione.
¿Alguien puede darme más detalles sobre esto? ¿Cómo implementaría una clase de error personalizada con un object
atributo? ¿Es correcto lo siguiente:
class MyCustomError < StandardError
attr_reader :object
def initialize(message, object)
super(message)
@object = object
end
end
Y entonces:
raise MyCustomError.new(anObject), "A message"
Llegar:
rescue MyCustomError => e
puts e.message # => "A message"
puts e.object # => anObject
¿Funcionará y, si lo hace, es esta la forma correcta de hacer las cosas?
rescue Exception => e
. Es más amplio que el predeterminadorescue => e
que se extiende desdeStandardError
y captura todo, incluido Ctrl + C. Yo haríarescue MyCustomError => e
.Respuestas:
raise
ya establece el mensaje para que no tenga que pasarlo al constructor:Lo reemplacé
rescue Exception
conrescue MyCustomError
, vea ¿Por qué es un mal estilo para `rescatar Excepción => e` en Ruby? .fuente
rescue Exception
, pero ¿por qué norescue MyCustomError
?raise MyCustomError, "a message"
sinnew
"un mensaje" no se establecerá.Dado lo que la documentación básica de ruby de
Exception
, de la que heredan todos los demás errores, establece sobre#message
http://ruby-doc.org/core-1.9.3/Exception.html#method-i-message
Optaría por redefinir
to_s
/to_str
o el inicializador. Aquí hay un ejemplo en el que queremos saber, de una manera legible principalmente por humanos, cuando un servicio externo no ha podido hacer algo.NOTA: La segunda estrategia a continuación utiliza los métodos de cadena de rieles bonitos, como
demodualize
, que puede ser un poco complicado y, por lo tanto, potencialmente imprudente en una excepción. También puede agregar más argumentos a la firma del método, si lo necesita.Anular la estrategia #to_s no #to_str, funciona de manera diferente
Salida de consola
Anulación de la estrategia #initialize
Esta es la estrategia más cercana a las implementaciones que he usado en rieles. Como se señaló anteriormente, utiliza los
demodualize
,underscore
yhumanize
ActiveSupport
métodos. Pero esto podría eliminarse fácilmente, como en la estrategia anterior.Salida de consola
Herramienta de demostración
Esta es una demostración para mostrar el rescate y la mensajería de la implementación anterior. La clase que genera las excepciones es una API falsa para Cloudinary. Simplemente descargue una de las estrategias anteriores en su consola de rieles, seguida de esto.
fuente
Tu idea es correcta, pero la forma en que la llamas es incorrecta. Debería ser
fuente
raise
palabra clave o algo.initialize
para tomar dos argumentos.new
pasa los argumentos ainitialize
.raise(BillRowError.new(:roamingcalls, @index), "Roaming Calls field missing")
. Entonces llamaraise
con dos parámetros: un nuevoBillRowError
objeto y su mensaje. Estoy confundido por la sintaxis ... En otros tutoriales siempre lo veo así:raise Error, message
raise
; eso es bastante flexible. El problema es que definióinitialize
tomar dos argumentos y solo dio uno. Mira tu ejemplo.BillRowError.new(:roamingcalls, @index)
se le dan dos argumentos.Quería hacer algo similar. Quería pasar un objeto a #new y tener el mensaje establecido en función de algún procesamiento del objeto pasado. Los siguientes trabajos.
Tenga en cuenta que si no declara
attr_accessor :message
, no funcionará. Al abordar el problema del OP, también puede pasar el mensaje como un argumento adicional y almacenar lo que quiera. La parte crucial parece ser #mensaje primordial.fuente