ruby-on-rails - formulario - ruby on rails ejemplos
¿Dónde definir tipos de error personalizados en Ruby y/o Rails? (5)
¿Existe una mejor práctica para definir tipos de error personalizados en una biblioteca Ruby (gema) o en la aplicación Ruby on Rails? Específicamente:
- ¿Dónde pertenecen estructuralmente en el proyecto? ¿Un archivo separado, con la definición del módulo / clase relevante, en otro lugar?
- ¿Hay alguna convención que establezca cuándo y cuándo no crear un nuevo tipo de error?
Diferentes bibliotecas tienen diferentes formas de hacer las cosas, y no he notado ningún patrón real. Algunas bibliotecas siempre usan tipos de error personalizados, mientras que otras no las utilizan en absoluto; algunos tienen todos los errores extendiendo StandardError mientras que otros tienen jerarquías anidadas; algunas son solo definiciones de clases vacías, otras tienen todo tipo de trucos ingeniosos.
Ah, y solo porque tengo ganas de llamar a estos "tipos de error" es un poco ambiguo, lo que quiero decir es esto:
class AuthenticationError < StandardError; end
class InvalidUsername < AuthenticationError; end
Creo que para tener archivos fuente coherentes en su proyecto, debe definir los errores en la clase en la que pueden arrojarse y en ninguna otra parte.
Algunas jerarquías pueden ser útiles, los espacios de nombres son buenos para evitar cadenas redundantes con nombres de tipos, pero eso es más una cuestión de gusto. No hay necesidad de exagerar siempre que tenga al menos un tipo de excepción personalizada en su aplicación que use para diferenciar entre casos de excepciones "intencionales" y "accidentales".
Esta es una vieja pregunta, pero quería compartir cómo manejo los errores personalizados en Rails, incluyendo adjuntar mensajes de error, probar y cómo manejar esto con los modelos de ActiveRecord
.
Creando un error personalizado
class MyClass
# create a custome error
class MissingRequirement < StandardError; end
def my_instance_method
raise MyClass::MissingRequirement, "My error msg" unless true
end
end
Prueba (minitest)
test "should raise MissingRequirement if ____ is missing"
# should raise an error
error = assert_raises(MyClass::MissingRequirement) {
MyClass.new.my_instance_method
}
assert error.message = "My error msg"
end
Con ActiveRecord
Creo que vale la pena señalar que si se trabaja con un modelo ActiveRecord
, un patrón popular es agregar un error al modelo como se describe a continuación, para que sus validaciones fallen:
def MyModel < ActiveRecord::Base
validate :code_does_not_contain_hyphens
def code_does_not_contain_hyphens
errors.add(:code, "cannot contain hyphens") if code.include?("-")
end
end
Cuando se ejecutan las validaciones, este método se ActiveRecord::RecordInvalid
la clase de error ActiveRecord::RecordInvalid
de ActiveRecord::RecordInvalid
y hará que las validaciones fallen.
¡Espero que esto ayude!
Para asegurarse de que la carga automática funciona como se espera en Rails 4.1.10 para múltiples clases de error personalizadas, querrá especificar archivos separados para cada una. Esto debería funcionar en el desarrollo con su recarga dinámica.
Así es como configuro errores en un proyecto reciente:
En lib/app_name/error/base.rb
module AppName
module Error
class Base < StandardError; end
end
end
y en los errores personalizados posteriores, como en lib/app_name/error/bad_stuff.rb
module AppName
module Error
class BadStuff < ::AppName::Error::Base; end
end
end
Debería poder llamar sus errores a través de:
raise AppName::Error::BadStuff.new("Bad stuff just happened")
en rieles puedes hacer el directorio de app/errors
# app/errors/foo_error.rb
class FooError < StandardError; end
reinicie spring / server y debería recogerlo
Para gemas
He visto muchas veces que defines excepciones de esta manera:
gem_dir / lib / gem_name / exceptions.rb
y definido como:
module GemName
class AuthenticationError < StandardError; end
class InvalidUsername < AuthenticationError; end
end
un ejemplo de esto sería algo como esto en httparty
Para Ruby on Rails
Póngalos en su carpeta lib / bajo un archivo llamado exceptions.rb, que se vería así:
module Exceptions
class AuthenticationError < StandardError; end
class InvalidUsername < AuthenticationError; end
end
y lo usarías así:
raise Exceptions::InvalidUsername