Handling Exceptions in Rails

0

How can I do Rails 4 to see the exception captured in my view:

rescue Exception => exc  
  # dispone el mensaje de error 
  puts "Error ".concat(exc.message)

In the terminal it shows me well, but when I want to pass to the view I can not show exceptions from the database specifically Postgresql of a trigger that has a validation.

So I have my code:

This my driver

def accion
  # Código que puede generar una excepción
rescue Exception => exc  
  # dispone el mensaje de error 
  puts "Aqui si muestra en la terminal ".concat(exc.message)
  @msg = "ERROR: Aqui nada.".concat(exc.message)

  respond_to do |f|
    f.js
  end
end

In my view I have this way

<% if @registro %>
   $("<div class='col-sm-12' id='msg-agregar-persona' style='color:#000;padding-top:5px;font-size:10px;background:#d6ffd6;border-radius:5px;text-align:center;'>Registrado Exitosamente.</div>").insertBefore("#form-agregar-persona");
<% else %>
  $("<div class='col-sm-12' id='msg-agregar-persona' style='color:#000;padding-top:5px;font-size:10px;background: #f8dfdf;border-radius:5px;text-align:center;'><%= @msg %></div>").insertBefore("#form-agregar-persona");
<% end %>

And in the console it shows me:

Persona Load (0.3ms)  SELECT "personas".* FROM "personas"  WHERE (documento_persona = '-123' and tipo_documento_id = 1 and nacionalidad_id = 1)
  (0.1ms)  BEGIN
  SQL (0.5ms)  INSERT INTO "personas" ("acta", "apellido_persona", "created_at", "documento_persona", "fecha_nacimiento", "folio", "genero_id", "libro", "nacionalidad_id", "nombre_persona", "tipo_documento_id", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING "id"  [["acta", ""], ["apellido_persona", "portíllo soto"], ["created_at", "2017-06-16 15:35:49.825920"], ["documento_persona", "-123"], ["fecha_nacimiento", "2017-06-30"], ["folio", ""], ["genero_id", 2], ["libro", ""], ["nacionalidad_id", 1], ["nombre_persona", "antonio ramón"], ["tipo_documento_id", 1], ["updated_at", "2017-06-16 15:35:49.825920"]]
  PG::Error: ERROR:  La fecha de nacimiento no puede ser igual o mayor a la fecha actual. Verifique la fecha ingresada
  : INSERT INTO "personas" ("acta", "apellido_persona", "created_at", "documento_persona", "fecha_nacimiento", "folio", "genero_id", "libro", "nacionalidad_id", "nombre_persona", "tipo_documento_id", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING "id"
  (0.1ms)  ROLLBACK

Here is the error:

PG::Error: ERROR:  La fecha de nacimiento no puede ser igual o mayor a la fecha actual. Verifique la fecha ingresada
: INSERT INTO "personas" ("acta", "apellido_persona", "created_at", "documento_persona", "fecha_nacimiento", "folio", "genero_id", "libro", "nacionalidad_id", "nombre_persona", "tipo_documento_id", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING "id"
""
Rendered personas/guardar.js.erb (0.1ms)
Completed 200 OK in 25ms (Views: 1.4ms | ActiveRecord: 17.8ms)
def accion
  # Código que puede generar una excepción
rescue => e
  @error = e.message
end
     

accion.html.erb

<p>Se generó el siguiente error: <%= @error %></p>

I already tried to do this step before but it does not show me and it does not generate any more errors:

The records that are displayed in the console:

 PG::Error: ERROR:  La fecha de nacimiento no puede ser igual o mayor a la fecha actual. Verifique la fecha ingresada
: INSERT INTO "personas" ("acta", "apellido_persona", "created_at", "documento_persona", "fecha_nacimiento", "folio", "genero_id", "libro", "nacionalidad_id", "nombre_persona", "tipo_documento_id", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING "id"
  Rendered personas/guardar.js.erb (0.0ms)
Completed 200 OK in 33ms (Views: 1.2ms | ActiveRecord: 26.9ms)
    
asked by Antonio 15.06.2017 в 23:11
source

1 answer

2

You can save the message of your exception in a variable and use it in your view as you would with any other variable, for example:

driver.rb

def accion
  # Código que puede generar una excepción
rescue Exception => exc  
  # dispone el mensaje de error 
  @msg = "ERROR: ".concat(exc.message)

  respond_to do |f|
    f.js
  end
end

accion.js.erb

$("<div><%= j(@msg) %></div>").insertBefore("#form-agregar-persona");

It is essential to use j() (or escape_javascript() ) to indicate that the value of @msg is not javascript and therefore treat it as a text (or string ) otherwise it will generate an error because it will try to execute it as a javascript tag.

Having said that, I would recommend making a better error handling, specifically adding validations in your model to avoid all exceptions that are generated at the database level.

For example: consider a% Usuario with fields nombre and edad , where edad is a numeric field in the database; If you send a data type text, an error like the one you have now will be generated, but we add validations to avoid it.

user.rb

class Usuario < ApplicationRecord
  validates :edad, numericality: { only_integer: true }
end

That validation will check that in effect the edad attribute is numeric before to save it in the database and, if it fails, it will add an error similar to Edad must be a number (which you can translate into your locales ) on the object that is calling you; for example:

@usuario = Usuario.new(nombre: "Antonio", edad: "diez")
@usuario.save
#=> false

@usuario.errors.full_messages
#=> ["Edad must be a number"]

Then, instead of using an exception and capturing the error message in a variable, you simply use validations and show the errors of the object, if they exist, for example:

accion.html.erb

<p>Se generó el siguiente error: <%= @usuario.errors.full_messages %></p>

This is just an example of everything you can achieve with validations, I recommend reading the Rails guide to see all the options you have to validate the information. This is the correct flow that must be followed; Caching exceptions is much more expensive for your application so, as far as possible, it is better to avoid them.

    
answered by 15.06.2017 / 23:17
source