2

我有一个在 tomcat 下运行的 jruby rails 应用程序。url 中的某些格式错误的查询字符串会导致 Rack 在生产模式下显示异常堆栈跟踪而阻塞。有没有办法优雅地处理它。我不认为我可以使用 config.exception_app 因为它只会处理从 rails 应用程序生成的异常。在这种情况下,异常会在到达 rails 应用程序之前生成。这是一个例外:

org.jruby.exceptions.RaiseException: (ArgumentError) invalid %-encoding (/"{}\%#$())
    at Module.decode_www_form_component(jar:file:/usr/local/apache-
tomcat/webapps/ROOT/WEB-INF/lib/gems-gems-jruby-jars-1.7.3-lib-jruby-stdlib-
1.7.3.jar!/META-INF/jruby.home/lib/ruby/1.9/uri/common.rb:898)
    at Rack::Utils.unescape(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/utils.rb:41)
    at Rack::Utils.parse_nested_query(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/utils.rb:94)
    at org.jruby.RubyArray.map(org/jruby/RubyArray.java:2361)
    at Rack::Utils.parse_nested_query(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/utils.rb:94)
    at org.jruby.RubyArray.each(org/jruby/RubyArray.java:1613)
    at Rack::Utils.parse_nested_query(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/utils.rb:93)
    at Rack::Request.parse_query(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/request.rb:332)
    at Rack::Request.POST(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/request.rb:209)
    at Rack::MethodOverride.method_override(/usr/local/apache-
tomcat/webapps/ROOT/WEB-INF/gems/gems/rack-1.4.5/lib/rack/methodoverride.rb:26)
    at Rack::MethodOverride.call(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/methodoverride.rb:14)
    at Rack::Runtime.call(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/runtime.rb:17)
    at ActiveSupport::Cache::Strategy::LocalCache::Middleware.call(/usr/local/apache-
tomcat/webapps/ROOT/WEB-INF/gems/gems/activesupport-
3.2.13/lib/active_support/cache/strategy/local_cache.rb:72)
    at Rack::Lock.call(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-1.4.5/lib/rack/lock.rb:15)
    at Rack::Cache::Context.forward(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-cache-1.2/lib/rack/cache/context.rb:136)
    at Rack::Cache::Context.pass(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-cache-1.2/lib/rack/cache/context.rb:143)
    at Rack::Cache::Context.invalidate(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-cache-1.2/lib/rack/cache/context.rb:155)
    at Rack::Cache::Context.call!(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-cache-1.2/lib/rack/cache/context.rb:71)
    at Rack::Cache::Context.call(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/rack-cache-1.2/lib/rack/cache/context.rb:51)
    at Rails::Engine.call(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/railties-3.2.13/lib/rails/engine.rb:479)
    at Rails::Application.call(/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/gems/gems/railties-3.2.13/lib/rails/application.rb:223)
    at Rack::Handler::Servlet.call(file:/usr/local/apache-tomcat/webapps/ROOT/WEB-
INF/lib/gems-gems-jruby-rack-1.1.13.1-lib-jruby-rack-
1.1.13.1.jar!/rack/handler/servlet.rb:22) 
4

2 回答 2

0

我最终编写了一个机架中间件来优雅地处理异常。我在 MethodOverride 中间件之前插入中间件,这是它引发异常的地方。

于 2013-07-25T22:11:30.923 回答
0

如果 Ruby 运行时已启动 - 在这种情况下似乎是……您应该能够配置一个(最小)机架错误应用程序,只需将 smt rack-y ( require 'my_error_app'; run MyErrorApp) 设置为jruby.rack.error.app上下文参数(例如在你的web.xml中使用 Warbler)

于 2013-07-23T16:40:29.737 回答