use*_*110 11 ruby-on-rails ruby-on-rails-4
我在调试模式下使用Rails控制台非常多,而且只需要更改控制台窗口的大小就有点乏味,这样我就可以找到列表顶部而无需滚动.
我认为BacktraceCleaner可以帮助解决这个问题,但我无法让它在控制台中保持沉默.
我把这段代码放在我的应用程序的初始化器中.
bc = Rails.backtrace_cleaner
bc.add_filter { |line| line.gsub(Rails.root.to_s, '<root>') }
bc.add_silencer { |line| line.index('<root>').nil? and line.index('/') == 0 }
bc.add_silencer { |line| line.index('<root>/vendor/') == 0 }
bc.add_silencer { |line| line =~ /console.rb/ }
bc.add_silencer { |line| line =~ /ruby-debug.ide.rb/ }
bc.add_silencer { |line| line =~ /rdebug-ide/ }
Run Code Online (Sandbox Code Playgroud)
但对控制台错误没有影响.所以我直接在控制台中尝试了它:
>>bc = Rails.backtrace_cleaner
>>bc.add_silencer { |line| line =~ /console.rb/ }
>> 1/0
ZeroDivisionError: divided by 0
from (irb):23:in `/'
from (irb):23
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/railties-4.0.3/lib/rails/commands /console.rb:90:in `start'
from C:/Ruby193/lib/ruby/gems/1.9.1/gems/railties-4.0.3/lib/rails/commands/console.rb:9:in `start'
Run Code Online (Sandbox Code Playgroud)
- 仍然看到包含'console.rb'的回溯线.Rails.backtrace_cleaner是否返回了一些不是Rails控制台环境中使用的清理程序?
如何在控制台回溯中获得(或安装)回溯清理器的句柄?
问题在于 IRB 控制台实现了自己的硬连线回溯消音器,该消音器与 Rails 的消音器不同。但它可以通过猴子修补 IRB 来覆盖。
从IRB的源代码中我们可以看到,这里使用WorkSpace类filter_backtrace中的方法调用消音器。因此,我们可以修补此方法,以在默认 IRB 的基础上使用 Rails 消音器。
该补丁可以放入 Rails 初始化程序中,但我认为更简洁的方法是使用IRB_RC可以设置为任何 ruby 代码并在 IRB 初始化期间调用的配置变量。因此,我们将仅将补丁保留在 IRB 的上下文中,并且不会影响 Rails 应用程序代码本身。
以下代码转到~/.irbrc:
if ENV['RAILS_ENV']
# silence console backtraces using BacktraceSilencer from Rails
IRB.conf[:IRB_RC] = Proc.new do
class IRB::WorkSpace
alias_method :orig_filter_backtrace, :filter_backtrace
def filter_backtrace(bt)
filtered_bt = orig_filter_backtrace(bt)
# The Rails silencer operates on the whole backtrace therefore
# we need to temporarily convert the particular trace line to an array
rails_backtrace_cleaner.clean(Array(filtered_bt)).first
end
private
def rails_backtrace_cleaner
Rails.backtrace_cleaner
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
正如代码中所注释的,我们需要处理一个小问题 - Rails 消音器对整个回溯进行操作(作为行数组传递),而 IRB 的消音方法是为每一行单独调用的。这就是为什么该行在传递到 Rails 消音器之前会暂时转换为数组的原因。
如果您确实想要一个自定义消音器,而不是 Rails 消音器,请使用类似以下的内容:
def rails_backtrace_cleaner
@rails_backtrace_cleaner ||= begin
bc = ActiveSupport::BacktraceCleaner.new
bc.add_filter { |line| line.gsub(Rails.root.to_s, '<root>') }
bc.add_silencer { |line| line.index('<root>').nil? and line.index('/') == 0 }
bc.add_silencer { |line| line.index('<root>/vendor/') == 0 }
bc.add_silencer { |line| line =~ /console.rb/ }
bc.add_silencer { |line| line =~ /ruby-debug.ide.rb/ }
bc.add_silencer { |line| line =~ /rdebug-ide/ }
bc
end
end
Run Code Online (Sandbox Code Playgroud)
$ rails c
Loading development environment (Rails 4.2.5.1)
>> 1/0
ZeroDivisionError: divided by 0
>>
Run Code Online (Sandbox Code Playgroud)
模型方法内引发异常的示例:
$ rails c
Loading development environment (Rails 4.2.5.1)
>> BaseUser.find(1234).update_rating
RuntimeError: Exception occured!
from app/models/base_user.rb:51:in `update_rating'
>>
Run Code Online (Sandbox Code Playgroud)
可以看出,Rails 内部堆栈跟踪行被静音,并且 Rails 根路径被过滤掉。
| 归档时间: |
|
| 查看次数: |
1079 次 |
| 最近记录: |