rails modulos mapas manejo errores ruby exception

modulos - ¿Cuál es la diferencia entre elevar excepciones y arrojar excepciones en Ruby?



rescue in ruby (3)

Ruby tiene dos mecanismos de excepción diferentes: Lanzar / Atrapar y Elevar / Rescatar.

¿Por qué tenemos dos?

¿Cuándo deberías usar uno y no el otro?


Creo que http://hasno.info/ruby-gotchas-and-caveats tiene una explicación decente de la diferencia:

catch / throw no son lo mismo que raise / rescue. catch / throw le permite salir rápidamente de bloques hasta un punto donde se define un catch para un símbolo específico, raise rescue es la excepción real que maneja cosas que involucran el objeto Exception.


https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raise ofrece una excelente explicación que dudo que pueda mejorar. Para resumir, copiar algunos ejemplos de código de la publicación del blog a medida que avanzo:

  1. raise / rescue son los análogos más cercanos a la construcción throw / catch que estás familiarizado de otros idiomas (o Python''s raise / except ). Si ha encontrado una condición de error y la throw en otro idioma, debe raise en Ruby.

  2. El throw / catch Ruby te permite romper la ejecución y subir la pila buscando una catch (como raise / rescue ), pero en realidad no está hecha para condiciones de error. Se debe usar con poca frecuencia, y solo existe cuando el comportamiento de "subir la pila hasta encontrar la catch correspondiente" tiene sentido para un algoritmo que está escribiendo, pero no tendría sentido pensar que el throw corresponde a una condición de error

    ¿Para qué se utilizan catch and throw en Ruby? ofrece algunas sugerencias sobre buenos usos de la construcción throw / catch .

Las diferencias de comportamiento concretas entre ellos incluyen:

  • rescue Foo rescatará instancias de Foo incluidas las subclases de Foo . catch(foo) solo atrapará el mismo objeto, Foo . No solo no puede pasar un nombre de clase para capturar instancias de él, sino que ni siquiera hará comparaciones de igualdad. Por ejemplo

    catch("foo") do throw "foo" end

    le dará un UncaughtThrowError: uncaught throw "foo" (o un ArgumentError en versiones de Ruby anteriores a 2.2)

  • Se pueden enumerar varias cláusulas de rescate ...

    begin do_something_error_prone rescue AParticularKindOfError # Insert heroism here. rescue write_to_error_log raise end

    mientras que múltiples catch deben ser anidadas ...

    catch :foo do catch :bar do do_something_that_can_throw_foo_or_bar end end

  • Un rescue simple equivale a rescue StandardError y es una construcción idiomática. Una " catch descubierto", como catch() {throw :foo} , nunca atrapará nada y no debería usarse.


  • raise , fail , rescue y ensure errores de manejo, también conocidos como excepciones
  • throw y catch son flujo de control

A diferencia de otros idiomas, el lanzamiento y la captura de Ruby no se usan para excepciones. En cambio, proporcionan una forma de terminar la ejecución anticipadamente cuando no se necesita más trabajo. (Grimm, 2011)

La terminación de un solo nivel de flujo de control, como un ciclo while, se puede hacer con un simple return . La terminación de muchos niveles de flujo de control, como un ciclo anidado, se puede hacer con throw .

Si bien el mecanismo de excepción de rescatar y rescatar es excelente para abandonar la ejecución cuando las cosas van mal, a veces es bueno poder saltar de una construcción profundamente anidada durante el procesamiento normal. Aquí es donde atrapar y lanzar son útiles. (Thomas y Hunt, 2001)

Referencias

  1. Grimm, Avdi. "Lanzar, atrapar, levantar, rescatar ... ¡Estoy tan confundido!" Blog de RubyLearning. Np, 11 de julio de 2011. Web. 1 de enero de 2012. http://rubylearning.com/blog/2011/07/12/throw-catch-raise-rescue--im-so-confused/ .
  2. Thomas, Dave y Andrew Hunt. "Programando a Ruby". : La guía del programador pragmático. Np, 2001. Web. 29 de septiembre de 2015. http://ruby-doc.com/docs/ProgrammingRuby/html/tut_exceptions.html .