1

I've tried to rescue from RecordNotFound error in controller like this:

  def create_user_role
    authorize User
    role = params[:user][:rolify_role].to_sym
    resource_type = params[:user][:resource_type]
    resource_id = params[:user][:id]

    # Catch RecordNotFound doesn't work
    begin
      resource = nil
      resource = resource_type.constantize.find(resource_id) if RolifyRoles.available_resources.include?(resource_type) && resource_id.present?
    rescue ActiveRecord::RecordNotFound => e
      format.html { render :show }
      flash[:error] = e.message
    end
  end

And when the resource_type.constantize.find(resource_id) cannot find the record, its doesn't caught by the rescue block.

 Completed 500 Internal Server Error in 46ms (ActiveRecord: 3.2ms)
 ActiveRecord::RecordNotFound - Couldn't find RequestComment with 'id'=1:
 app/controllers/users_controller.rb:58:in `create_user_role'

I've tried to rescue with StandardError or even with Exception and result was the same.

Where is the problem?

I am also calling a method from my module which raise some exceptions, which also aren't handled.

Backtrace:

07:23:29 web.1     | Started POST "/users/kru0096/create_user_role" for 10.0.131.29 at 2018-06-13 07:23:29 +0200
07:23:39 web.1     | Processing by UsersController#create_user_role as HTML
07:23:39 web.1     |   Parameters: {"utf8"=>"✓", "authenticity_token"=>"5kN6MuoP4YntbTvL5cTDPuCZypDdO
o1KPcvIu8dJ6otX0aYPwuWg64/TTTgDe6DRXn6wCs1KvgT9xjkr9g/dyA==", "user"=>{"rolify_role"=>"hoac", "resource_type"=>"RequestComment", "id"=>"1"}, "commit"=>"", "id"=>"kru0096"}
07:23:39 web.1     |   User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
07:23:39 web.1     |   User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE `users`.`login` = 'kru0096' LIMIT 1
07:23:39 web.1     |   RequestComment Load (0.3ms)  SELECT  `request_comments`.* FROM `request_comments` WHERE `request_comments`.`id` = 1 LIMIT 1
07:23:39 web.1     | Completed 500 Internal Server Error in 41ms (ActiveRecord: 6.5ms)
07:23:39 web.1     | 
07:23:39 web.1     | 
07:23:39 web.1     | 
07:23:39 web.1     | ActiveRecord::RecordNotFound - Couldn't find RequestComment with 'id'=1:
07:23:39 web.1     |   app/controllers/users_controller.rb:92:in `create_user_role'
07:23:39 web.1     | 
Jan Krupa
  • 484
  • 9
  • 21

2 Answers2

0

it looks like its catching the error correctly, I am wondering if the real problem is the ordering of the code in the rescue statement. try setting the flash before the render call.

rescue ActiveRecord::RecordNotFound => e
  flash[:error] = e.message
  format.html { render :show }
end

to me, it looks like your returning the error.message and not the render statement. Likewise, you could also try render :show, flash: { error: e.message }

heinztomato
  • 795
  • 1
  • 7
  • 12
  • I tried it, but still, the exception occurred and `rescue` block is not in use. – Jan Krupa Jun 13 '18 at 05:20
  • I've added backtrace to the question. – Jan Krupa Jun 13 '18 at 05:26
  • is that the entire backtrace? a 500 internal server error basically means rails does not know how to handle the error it received. You can also try to add a `rescue_from` statement on `ActiveRecord::RecordNotFound` to try and catch this error - https://medium.com/spritle-software/handle-activerecord-recordnotfound-more-elegantly-11891c80a644 http://api.rubyonrails.org/classes/ActiveSupport/Rescuable/ClassMethods.html – heinztomato Jun 14 '18 at 08:39
  • I tried `rescue_from` statement, and the result was the same. I changed the controller method, where rescue is defined in the `respond_to` block, and catch works fine now. – Jan Krupa Jun 18 '18 at 08:29
0

Exception handling starts working when the exception is caught at the respond_to block.

I also defined my own exception, but this has no effect on the result.

def create_user_role
    authorize User
    # Params Inicialization
    role = params[:user][:rolify_role].to_sym
    resource_type = params[:user][:resource_type]
    resource_id = params[:user][:id]

    respond_to do |format|
      begin
        # Make resource as instance of class or set to nil
        resource = RolifyRoles.build_resource(resource_type, resource_id)
        if @user.add_role role, resource
          format.html { redirect_to @user, notice: "Role #{role} was successfully added." }
          format.json { render :show, status: :created, location: @user }
        else
          format.html { render :show }
          format.json { render json: @user.errors, status: :unprocessable_entity }
        end
      # Catch self defined exceptions
      rescue RolifyRolesException => e
        flash[:error] = e.message
        flash.keep
        format.html { render :show, flash: { error: e.message } }
        format.json { render json: e.message, status: :unprocessable_entity }
      end
    end
  end
Jan Krupa
  • 484
  • 9
  • 21