救援在红宝石中不起作用的原因是什么?

时间:2016-04-18 10:46:51

标签: ruby

我正在调试有关simple_token_authentication的问题,我将https://github.com/gonzalo-bulnes/simple_token_authentication/blob/master/lib/simple_token_authentication/sign_in_handler.rb#L7中的一些代码修改为:

def sign_in(controller, record, *args)
  begin
    puts "=== TRACE 1"
    integrate_with_devise_trackable!(controller)
    puts "=== TRACE 2"
    controller.send(:sign_in, record, *args)
    puts "=== TRACE 3"
  rescue Exception => e
    puts "=== TRACE 4"
  ensure
    puts "=== TRACE 5"
  end
end

输出:

Started GET "/projects" for ::1 at 2016-04-18 18:35:22 +0800
  ActiveRecord::SchemaMigration Load (0.1ms)  SELECT "schema_migrations".* FROM "schema_migrations"
Processing by ProjectsController#index as JSON
  Parameters: {"project"=>{}}
  User Load (0.2ms)  SELECT  "users".* FROM "users" WHERE "users"."email" = ?  ORDER BY "users"."id" ASC LIMIT 1  [["email", "testaccount@gmail.com"]]
=== TRACE 1
=== TRACE 2
   (0.1ms)  begin transaction
   (0.0ms)  commit transaction
=== TRACE 5
Completed 401 Unauthorized in 40ms (ActiveRecord: 0.9ms)

问题不在于simple_token_authentication,问题是为什么TRACE 3TRACE 4都没有输出?是否有可能导致这种情况的原因?

我的环境:

  • 由rvm
  • 安装的ruby-2.2.3 [x86_64]
  • Mac OSX 10.11.4

1 个答案:

答案 0 :(得分:5)

设计和监护人使用throw/catch来表示监狱长无法签署用户。只要堆叠上有匹配的catch块,throw就不会# 39;提出异常,因此不会调用救援条款。确保被调用,因为它总是被调用。您可以使用以下小代码对此进行测试:

def test
  puts "about to throw"
  throw :rock, :hard
rescue Exception => e
  puts "exception: #{e.message}"
ensure
  puts "ensure"
end

result = catch(:rock) { test }
puts result

rescue条款无法执行,但如果您只是自己调用test,那么您将获得该块处理的UncaughtThrowException。< / p>

在这种情况下,设计提供了一个机架中间件,可以捕获监狱长抛出的东西。