“lib”目录

时间:2016-01-26 20:23:35

标签: ruby-on-rails exception-handling

我在我的Devise初始化程序中使用Wikipedia OmniAuth gem的包装器,定期抛出JWT::DecodeErrors。我正在尝试使用自定义错误消息来处理这些错误,而不是抛出500.(在这里坚持下去。)

在我的Devise初始化程序中,我设置了这样的策略:

  config.omniauth :mediawiki,
                  Figaro.env.wikipedia_token,
                  Figaro.env.wikipedia_secret,
                  strategy_class: CustomStrategy,
                  client_options: {
                    site: "https://#{Figaro.env.wiki_language}.wikipedia.org"
                  }

我的CustomStrategy继承了默认的MediaWiki策略,并将一些数据添加到request对象,以便稍后在ErrorsController中检查:

# lib/custom_strategy.rb

class LoginError < StandardError; end

class CustomStrategy < OmniAuth::Strategies::Mediawiki
  def parse_info(jwt_data)
    begin
      super
    rescue JWT::DecodeError
      request.env['JWT_ERROR'] = true
      request.env['JWT_DATA'] = jwt_data
      raise ::LoginError.new("\nA JWT::DecodeError occurred. Here is the web token data:\n#{jwt_data.body.inspect}")
    end
  end

end

所以在这里我尝试通过提出一个我希望在我的控制器中捕获的JWT::DecodeError来抓住LoginError

class ApplicationController < ActionController::Base
  rescue_from StandardError, with: :handle_login_error
  ...
  protected
  def handle_login_error
    redirect_to errors_login_error_path
  end
end

问题在于rescue_from only handles exceptions thrown in the controller

由于我的策略中存在此异常,因此我没有机会拯救它,Rails只将其视为500

[2016-01-26 12:10:02.183 FATAL] StandardError (
A JWT::DecodeError occurred. Here is the web token data:
"{\"error\":\"mwoauthdatastore-access-token-not-found\",\"message\":\"No approved grant was found for that authorization token.\"}"):
  lib/custom_strategy.rb:9:in `rescue in parse_info'
  lib/custom_strategy.rb:6:in `parse_info'
[2016-01-26 12:10:02.251 INFO ] Processing by ErrorsController#internal_server_error as HTML
[2016-01-26 12:10:02.251 INFO ] Parameters: {"oauth_verifier"=>"XXXXXXXXXXXXXXXX", "oauth_token"=>"XXXXXXXXXXXXXXX"}
[2016-01-26 12:10:02.971 INFO ] Rendered errors/internal_server_error.html.erb within layouts/application (3.8ms)
[2016-01-26 12:10:03.204 INFO ] Rendered shared/_head.html.haml (10.1ms)
[2016-01-26 12:10:03.215 INFO ] Rendered shared/_nav.html.haml (9.7ms)
[2016-01-26 12:10:03.218 INFO ] Rendered shared/_foot.html.haml (2.3ms)
[2016-01-26 12:10:03.219 INFO ] Completed 500 Internal Server Error in 967ms (Views: 265.8ms | ActiveRecord: 0.0ms)

所以在这里,Rails将其视为500,我使用custom error pages,而不是Rails默认值。

作为参考,这是我的ErrorsController

class ErrorsController < ApplicationController
  respond_to :html, :json

  def file_not_found
    render status: 404
  end

  def unprocessable
    render status: 422
  end

  def internal_server_error
    if request.env['JWT_ERROR']
      return login_error
    end
    render status: 500
  end

  def incorrect_passcode
    render status: 401
  end

  def login_error
    #return render status: 599
  end
end

处理jwt-ruby gem中发生的异常的最佳方法是什么,oauth-mediawiki gem是JWT::DecodeError gem的依赖项,我用自定义策略包装,希望捕获{{ 1}}并在我的应用程序中处理它?如果出现这个特定的错误,我想渲染一个特殊的视图,而不仅仅是500视图。

编辑2:进一步阐述问题

问题在于我无法找到一种方法来拯救我已经获救并重新引发(JWT::DecodeError)的异常,这种方式允许我渲染自定义视图。正如您在上面的日志中所看到的,它只是呈现ErrorsContoller#internal_server_error

0 个答案:

没有答案