首页 > 解决方案 > 如何调查 Rails 中的异常?

问题描述

我对 Rails 很陌生,这是我的第一个项目。您能帮我了解如何调查错误吗?

我使用 ransack 和地理编码编写了一个搜索功能,以根据对象的位置在数据库中显示对象。

我在这里遇到了一个例外:

@cars_address = Car.where(active: true).near(session[:loc_search], 5, order: 'distance')

我在控制台中收到此错误:

异常 = 不支持的参数类型:0(整数)

当我在我的搜索表单中输入长字符串时会发生错误,所有内容都适用于“米兰”之类的内容,但地理完整建议出现异常,例如“米兰,意大利米兰大都会””。

这是控制器:

  def search

if params[:q].present? && params[:q].strip != ""
  session[:loc_search] = params[:q]
end
if session[:loc_search] && session[:loc_search] != ""


  #Something Wrong Here?
  @cars_address = Car.where(active: true).near(session[:loc_search], 5, order: 'distance')
  else
  @cars_address = Car.where(active: true).all

end

@q = @cars_address.ransack(params[:q])
@cars = @q.result

@arrCars = @cars.to_a

这是异常的堆栈跟踪

 Processing by PagesController#search as HTML
  Parameters: {"q"=>"Milano, Metropolitan City of Milan, Italy", "start_date"=>"", "end_date"=>"", "commit"=>"Search"}

[4, 13] in /mnt/c/Users/haget/Documents/GitHub/Clapp/app/controllers/pages_controller.rb
    4:     @cars = Car.where(active: true).limit(3)
    5:   end
    6:
    7:   def search
    8:     byebug
=>  9:     if params[:q].present? && params[:q].strip != ""
   10:       session[:loc_search] = params[:q]
   11:     end
   12:     if session[:loc_search] && session[:loc_search] != ""
   13:
(byebug)

[95, 104] in /home/haget/.rvm/gems/ruby-2.7.0/gems/puma-4.3.5/lib/puma/thread_pool.rb
    95:         not_full = @not_full
    96:
    97:         extra = @extra.map { |i| i.new }
    98:
    99:         while true
=> 100:           work = nil
   101:
   102:           continue = true
   103:
   104:           mutex.synchronize do
(byebug)

[19, 28] in /home/haget/.rvm/gems/ruby-2.7.0/gems/actionpack-6.0.3.2/lib/action_controller/metal/rescue.rb
   19:
   20:     private
   21:       def process_action(*args)
   22:         super
   23:       rescue Exception => exception
=> 24:         request.env["action_dispatch.show_detailed_exceptions"] ||= show_detailed_exceptions?
   25:         rescue_with_handler(exception) || raise
   26:       end
   27:   end
   28: end
(byebug)

[32, 41] in /home/haget/.rvm/gems/ruby-2.7.0/gems/actionpack-6.0.3.2/lib/action_controller/metal/instrumentation.rb
   32:       ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
   33:         super.tap do
   34:           payload[:status] = response.status
   35:         end
   36:       ensure
=> 37:         append_info_to_payload(payload)
   38:       end
   39:     end
   40:
   41:     def render(*args)
(byebug)

[20, 29] in /home/haget/.rvm/gems/ruby-2.7.0/gems/activesupport-6.0.3.2/lib/active_support/notifications/instrumenter.rb
   20:       def instrument(name, payload = {})
   21:         # some of the listeners might have state
   22:         listeners_state = start name, payload
   23:         begin
   24:           yield payload if block_given?
=> 25:         rescue Exception => e
   26:           payload[:exception] = [e.class.name, e.message]
   27:           payload[:exception_object] = e
   28:           raise e
   29:         ensure
(byebug)
Completed 500 Internal Server Error in 13406ms (ActiveRecord: 0.0ms | Allocations: 788474)



[36, 45] in /home/haget/.rvm/gems/ruby-2.7.0/gems/actionview-6.0.3.2/lib/action_view/rendering.rb
   36:     # Overwrite process to setup I18n proxy.
   37:     def process(*) #:nodoc:
   38:       old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context)
   39:       super
   40:     ensure
=> 41:       I18n.config = old_config
   42:     end
   43:
   44:     module ClassMethods
   45:       def _routes
(byebug)

[25, 34] in /home/haget/.rvm/gems/ruby-2.7.0/gems/actionpack-6.0.3.2/lib/action_dispatch/middleware/callbacks.rb
   25:       error = nil
   26:       result = run_callbacks :call do
   27:         @app.call(env)
   28:       rescue => error
   29:       end
=> 30:       raise error if error
   31:       result
   32:     end
   33:   end
   34: end
(byebug)

[12, 21] in /home/haget/.rvm/gems/ruby-2.7.0/gems/actionpack-6.0.3.2/lib/action_dispatch/middleware/executor.rb
   12:       state = @executor.run!
   13:       begin
   14:         response = @app.call(env)
   15:         returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
   16:       ensure
=> 17:         state.complete! unless returned
   18:       end
   19:     end
   20:   end
   21: end
(byebug)

[36, 45] in /home/haget/.rvm/gems/ruby-2.7.0/gems/actionpack-6.0.3.2/lib/action_dispatch/middleware/debug_exceptions.rb
   36:         raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"
   37:       end
   38:
   39:       response
   40:     rescue Exception => exception
=> 41:       invoke_interceptors(request, exception)
   42:       raise exception unless request.show_exceptions?
   43:       render_exception(request, exception)
   44:     end
   45:
(byebug)

ArgumentError (Unsupported argument type: 0 (Integer)):

app/controllers/pages_controller.rb:16:in `search'

解决了

地理编码器本身无法从自动定位建议建议的一些长字符串中返回坐标,因此我不得不更改地理编码器:配置以告诉地理编码器从谷歌位置 api 获取坐标。

在 Geocoder 上关注这篇 Medium 文章

标签: ruby-on-railsrubyransackgeocomplete

解决方案


如果您忽略了部分异常回溯,您通常可以自己挽救异常并获得完整的跟踪:

irb(main):002:0> begin; blah; rescue => exc; end
=> nil

irb(main):003:0> exc
=> #<NameError: undefined local variable or method `blah' for main:Object>

irb(main):005:0> puts exc.backtrace.join("\n")
(irb):2:in `rescue in irb_binding'
(irb):1:in `irb_binding'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb/workspace.rb:114:in `eval'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb/workspace.rb:114:in `evaluate'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb/context.rb:439:in `evaluate'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb.rb:540:in `block (2 levels) in eval_input'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb.rb:695:in `signal_status'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb.rb:537:in `block in eval_input'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb/ruby-lex.rb:150:in `block (2 levels) in each_top_level_statement'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb/ruby-lex.rb:135:in `loop'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb/ruby-lex.rb:135:in `block in each_top_level_statement'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb/ruby-lex.rb:134:in `catch'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb/ruby-lex.rb:134:in `each_top_level_statement'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb.rb:536:in `eval_input'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb.rb:471:in `block in run'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb.rb:470:in `catch'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb.rb:470:in `run'
/home/w/.rbenv/versions/2.7.1/lib/ruby/2.7.0/irb.rb:399:in `start'
/home/w/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/irb-1.2.3/exe/irb:11:in `<top (required)>'
/home/w/.rbenv/versions/2.7/bin/irb:23:in `load'
/home/w/.rbenv/versions/2.7/bin/irb:23:in `<main>'
=> nil
irb(main):006:0> 

将“blah”替换为失败的表达式。

您也可以使用“s” byebug 命令来单步执行某个方法,尽管此策略可能需要一些时间才能找到实际失败的方法。


推荐阅读