try standard route rails how handling exceptions error custom catch ruby exception-handling

ruby - route - standard error rails



Excepciones de Ruby-¿Por qué “más”? (5)

Aquí hay un caso de uso concreto para else en una expresión de begin . Supongamos que está escribiendo pruebas automatizadas y desea escribir un método que devuelva el error generado por un bloque. Pero también desea que la prueba falle si el bloque no genera un error. Puedes hacerlo:

def get_error_from(&block) begin block.call rescue => err err # we want to return this else raise "No error was raised" end end

Tenga en cuenta que no puede mover la raise dentro del bloque de begin , porque se recuperará d. Por supuesto, hay otras formas sin usar else , como verificar si err es nil después del end , pero eso no es tan sucinto.

Personalmente, rara vez uso else de esta manera porque creo que rara vez se necesita, pero resulta útil en esos casos raros.

EDITAR

Se me ocurrió otro caso de uso. Aquí hay un begin / rescue típico:

begin do_something_that_may_raise_argument_error do_something_else_when_the_previous_line_doesnt_raise rescue ArgumentError => e handle_the_error end

¿Por qué esto es menos que ideal? Debido a que la intención es rescue cuando do_something_that_may_raise_argument_error genera ArgumentError , no cuando do_something_else_when_the_previous_line_doesnt_raise aumenta.

Por lo general, es mejor usar begin / rescue para ajustar el código mínimo que desea proteger de un raise , porque de lo contrario:

  • Puede enmascarar errores en el código que no se suponía que debía raise
  • La intención del rescue es más difícil de descifrar. Alguien (incluido tu yo futuro) puede leer el código y preguntarse "¿Qué expresión quería proteger? Se parece a la expresión ABC ... pero tal vez la expresión DEF también? ¿Qué pretendía el autor?" La refactorización se vuelve mucho más difícil.

Evitas esos problemas con este simple cambio:

begin do_something_that_may_raise_argument_error rescue ArgumentError => e handle_the_error else do_something_else_when_the_previous_line_doesnt_raise end

Estoy tratando de entender las excepciones en Ruby pero estoy un poco confundido. El tutorial que estoy usando dice que si se produce una excepción que no coincide con ninguna de las excepciones identificadas por las declaraciones de rescate, puede usar un "más" para capturarlo:

begin # - rescue OneTypeOfException # - rescue AnotherTypeOfException # - else # Other exceptions ensure # Always will be executed end

Sin embargo, también vi más adelante en el tutorial "rescate" que se usó sin una excepción especificada:

begin file = open("/unexistant_file") if file puts "File opened successfully" end rescue file = STDIN end print file, "==", STDIN, "/n"

Si puedes hacer esto, ¿entonces necesito usar alguna otra cosa? ¿O puedo simplemente usar un rescate genérico al final como este?

begin # - rescue OneTypeOfException # - rescue AnotherTypeOfException # - rescue # Other exceptions ensure # Always will be executed end


El bloque else en un bloque final de rescate de inicio se usa cuando quizás espera que ocurra una excepción de algún tipo. Si ejecuta todas las excepciones esperadas pero aún no ha generado nada, entonces en su bloque else puede hacer lo que sea necesario ahora que sabe que su código original no tuvo errores.


Gracias a else a veces puede fusionar dos bloques begin end anidados.
Entonces (ejemplo simplificado de mi código actual) en lugar de:

begin html = begin NetHTTPUtils.request_data url rescue NetHTTPUtils::Error => e raise unless 503 == e.code sleep 60 retry end redo unless html["market"] end

usted escribe:

begin html = NetHTTPUtils.request_data url rescue NetHTTPUtils::Error => e raise unless 503 == e.code sleep 60 retry else redo unless html["market"] end


La única razón por la que puedo ver el bloque else es si desea ejecutar algo antes del bloque ensure cuando el código en el bloque de begin no generó ningún error.

begin puts "Hello" rescue puts "Error" else puts "Success" ensure puts "my old friend" puts "I''ve come to talk with you again." end


La else es para cuando el bloque se completa sin una excepción lanzada. El ensure se ejecuta si el bloque se completa con éxito o no. Ejemplo:

begin puts "Hello, world!" rescue puts "rescue" else puts "else" ensure puts "ensure" end

Esto imprimirá Hello, world! , luego else , entonces ensure .