views:

34

answers:

1

In my controller, I have code that looks like the following:

    @mymodel.transaction do 
      for a in arr
        @mymodel.some_method(a)
      end
    end

in @mymodel#some_method I could throw an ActiveRecord::Rollback exception which in the db does what it needs to do, however I then simply get an HTTP 500 and no way to catch the exception to let the user know in an elegant way what went wrong.

I've tried wrapping @mymodel.transaction do in a begin/rescue block, but that won't do it either. What's the best way to catch the exception so I can present the proper view to the user?

A: 

From the ActiveRecord::Base documentation:

Normally, raising an exception will cause the transaction method to rollback the database transaction and pass on the exception. But if you raise an ActiveRecord::Rollback exception, then the database transaction will be rolled back, without passing on the exception.

A small example:

class ThrowController < ApplicationController
  def index
      status = ActiveRecord::Base.connection.transaction do
        raise ActiveRecord::Rollback.new
      end

      Rails.logger.info "followed transaction"
  end
end

then:

>> c = ThrowController.new.index
=> "followed transaction \n"

As you can see, the ActiveRecord:::Rollback exception is swallowed by the transaction block.

It seems to me that something else is going on with your code that we're not aware of.

rjk
Have tried that also, still no go, get an http 500 because the exception isn't being handled.
randombits
try the begin rescue outside the transaction block
Rishav Rastogi
I reworked my answer with a better example from the documentation. I think we need more code from you that exhibits the 500 error.
rjk