开发者

Why can't we access local variable inside rescue?

开发者 https://www.devze.com 2023-01-23 05:02 出处:网络
Local Variable begin transaction#Code inside transaction object = Class.new attributes raise unless object.save!

Local Variable

begin
  transaction  #Code inside transaction 
    object = Class.new attributes
    raise unless object.save!
  end 
rescue
  puts object.error.full_messages # Why can't we use local varible inside rescue ?
end

Instance Variable

begin
  transaction  #Code inside transaction 
    @object = Class.new attributes
    raise unless @object.sav开发者_StackOverflow中文版e!
  end 
rescue
  puts @object.error.full_messages # This is working fine.
end


You most certainly can access local variables defined in a begin, in the corresponding rescue block (assuming of course, the exception has been raised, after the variable was set).

What you can't do is access local variables that are defined inside a block, outside of the block. This has nothing to do with exceptions. See this simple example:

define transaction() yield end
transaction do
  x = 42
end
puts x # This will cause an error because `x` is not defined here.

What you can do to fix this, is to define the variable before the block (you can just set it to nil) and then set it inside the block.

x = nil
transaction do
  x = 42
end
puts x # Will print 42

So if you change your code like this, it will work:

begin
  object = nil
  transaction do  #Code inside transaction 
    object = Class.new attributes
    raise unless object.save!
  end 
rescue
  puts object.error.full_messages # Why can't we use local varible inside rescue ?
end


You can pick up error message from ActiveRecord::RecordInvalid. It can be seen on official document example here.

https://api.rubyonrails.org/v6.1.3.2/classes/ActiveRecord/RecordInvalid.html

begin
  transaction
    Class.create! attributes
  end 
rescue ActiveRecord::RecordInvalid => invalid
  puts invalid.record.error.full_messages
end

0

精彩评论

暂无评论...
验证码 换一张
取 消