¿Cómo puedo generar una excepción en Rails para que se comporte como otras excepciones de Rails?

91

Me gustaría generar una excepción para que haga lo mismo que una excepción normal de Rails. Especialmente, muestre la excepción y el seguimiento de la pila en el modo de desarrollo y muestre la página "Lo sentimos, pero algo salió mal" en el modo de producción.

Intenté lo siguiente:

raise "safety_care group missing!" if group.nil?

Pero simplemente escribe "ERROR signing up, group missing!"en el archivo development.log

Chirag Patel
fuente
2
el mensaje de error que publicó no parece provenir de esta excepción (es un mensaje diferente) ¿Es esto realmente lo que está viendo?
levinalex

Respuestas:

139

No tienes que hacer nada especial, debería estar funcionando.

Cuando tengo una nueva aplicación de rieles con este controlador:

class FooController < ApplicationController
  def index
    raise "error"
  end
end

E ir a http://127.0.0.1:3000/foo/

Veo la excepción con un seguimiento de pila.

Es posible que no vea todo el seguimiento de la pila en el registro de la consola porque Rails (desde 2.3) filtra las líneas del seguimiento de la pila que provienen del propio marco.

Ver config/initializers/backtrace_silencers.rben su proyecto Rails

levinalex
fuente
2
Excelente respuesta concisa.
registro
1
El enlace de skitch (que ve la excepción con un seguimiento de pila) ya no funciona
Asaf
@levinalex, ¿será seguro en el modo de producción para mostrar el seguimiento de la pila?
BKSpurgeon
@levinalex - gracias Alex. ¿Hay alguna forma de agregar una cadena personalizada al mensaje de error?
BKSpurgeon
62

Puedes hacerlo así:

class UsersController < ApplicationController
  ## Exception Handling
  class NotActivated < StandardError
  end

  rescue_from NotActivated, :with => :not_activated

  def not_activated(exception)
    flash[:notice] = "This user is not activated."
    Event.new_event "Exception: #{exception.message}", current_user, request.remote_ip
    redirect_to "/"
  end

  def show
      // Do something that fails..
      raise NotActivated unless @user.is_activated?
  end
end

Lo que está haciendo aquí es crear una clase "NotActivated" que servirá como excepción. Al usar raise, puede lanzar "NotActivated" como una excepción. rescue_from es la forma de detectar una excepción con un método especificado (no_activado en este caso). Un ejemplo bastante largo, pero debería mostrarte cómo funciona.

Mis mejores deseos,
Fabián

Halfdan
fuente
Esto no muestra la excepción y el seguimiento de la pila en el modo de desarrollo y muestra la página "Lo sentimos, pero algo salió mal" en el modo de producción.
Chirag Patel
2
La página "lo sentimos" es en realidad el controlador de errores 500 de su servidor web. Verifique su archivo .htaccess y generalmente lo verá allí
Jeff Paquette
Tal vez no sea una respuesta al OP, sino un ejemplo muy útil, ¡gracias!
Neil Stockbridge
11

Si necesita una forma más fácil de hacerlo y no quiere mucho alboroto, una ejecución simple podría ser:

raise Exception.new('something bad happened!')

Esto generará una excepción, digamos econe.message = something bad happened!

y luego puede rescatarlo como está rescatando todas las demás excepciones en general.

Sambhav Sharma
fuente
No es una buena idea generar o rescatar 'Exception' en sí, intente usar StandardError en su lugar. Vea esto para más detalles: stackoverflow.com/questions/10048173/…
Ekamjit Singh