2011-08-30 12 views
15

Aquí está la situación. Quiero que todas las excepciones en doStuff() aparezcan en el código para que se manejen en un nivel superior.Excepción de resubida de Ruby con argumento de cadena adicional

También me gustaría grabar la frecuencia cualquier excepciones están sucediendo en hacerTarea() a un nivel superior, así, y actualmente estoy haciendo esto:

begin 
    doStuff() 
rescue Exception => 
    raise e, "specific error to log in a db" 

código hacerTarea lanzar decenas de excepciones, y quiero capturar cada uno de estos eventos para poner en el db. Hay un doStuff2(), que también puede arrojar instrucciones idénticas, y quiero saber de qué función provienen.

Agregando la cadena adicional, parece que cambia la excepción en sí misma, y ​​pierdo todo el formato agradable y la información de rastreo que tenía la excepción original.

¿Alguna sugerencia sobre cómo puedo volver a publicar la excepción original, pero también realizar un seguimiento de todas las excepciones que se producen dentro de doStuff()?

Respuesta

48

Si llama al raise sin pasar ningún argumento, Ruby volverá a plantear la última excepción.

begin 
    doStuff() 
rescue => e 
    log_exception(e) 
    raise # This will re-raise the last exception. 
end 

Como nota al margen, me gustaría darle algunas sugerencias sobre las mejores prácticas de Ruby.

  1. doStuff() método no cumple con las convenciones de nomenclatura de Ruby. Deberías usar guiones bajos para los métodos. Por favor use do_stuff. Además, no es necesario usar () si no hay argumentos.
  2. Nunca rescates la excepción, en su lugar rescata la clase más baja de nivel que necesitas rescatar. En la mayoría de los casos, es posible que desee rescatar todo tipo de StandardError o RuntimeError. De hecho, si usa rescue sin pasar el tipo de error, Ruby rescatará automáticamente cualquier subclase de StandardError. Exception clase es de muy bajo nivel y detectará también errores de sintaxis y varios otros problemas del compilador. Es posible que desee dejar que la aplicación se bloquee en este caso para que no implemente una aplicación defectuosa.
+0

hacerTarea() era sólo de pseudo código, lo siento. El problema es que no puedo registrar la excepción aquí. El registro debe ocurrir a un nivel superior. Esta aplicación es 'tonta' y no sabe nada sobre bases de datos o registro. Sé que no puedo plantear 2 excepciones simultáneamente, pero esto resolvería mi problema. Uno de ellos sería atrapado y conectado, y el otro aún aparecería en el código. –

2

No puede generar una nueva excepción y guardar la excepción anterior y su stacktrace fuera de la caja. Las excepciones anidadas del mundo de Java no están desactualizadas aquí desafortunadamente. Estará disponible en Ruby 2.1. Es un tema bastante candente. https://bugs.ruby-lang.org/issues/8257

Aún puede usar nesty gema para tenerlo. Lo que solo necesita es include Nesty::NestedError en sus clases de excepción. Más información está aquí: https://github.com/skorks/nesty/

3

Puede guardar la traza y el mensaje de la primera excepción y construir una nueva excepción para elevar

begin 
rescue Exception => e 
    new_ex = Exception.new("Error while executing ...:#{e.message}") 
    new_ex.set_backtrace(e.backtrace) 
    raise new_ex 
end 
Cuestiones relacionadas