bullet
bullet copied to clipboard
Incorrect semantics for Bullet.stacktrace_excludes
According to the readme:
Bullet.stacktrace_excludes
: ignore paths with any of these substrings in the stack trace, even if they are not in your main app.
However the option does not appear to be actually working that way. My application uses Rails Admin and I've been getting frequent UnoptimizedQueryErrors for the admin code which I'd like to ignore. I set Bullet.stacktrace_excludes = ['rails_admin']
in my application configuration, but it does not cause Rails Admin errors to be ignored.
After stepping through a debugger, I believe I've found the offending line of code in lib/bullet/detector/n_plus_one_query.rb
:
def excluded_stacktrace_path?
Bullet.stacktrace_excludes.any? do |excluded_path|
caller_in_project.any? { |c| c.include?(excluded_path) }
end
end
If this method returns true
then the failure gets ignored. Since caller_in_project
only returns stack trace lines that are considered to be "in the project", none of them match my "rails_admin" filter since that's an external gem, and the failure does not get filtered.
That middle line should really be the following
caller.any? { |c| c.include?(excluded_path) }
to match the semantics the readme describes of "ignoring paths with any of these substrings in the stack trace, even if they are not in your main app."
As a workaround, I'm able to also add 'rails_admin'
to Bullet.stacktrace_includes
to make Bullet think that rails_admin is a part of my codebase, but this is unintuitive and does not match the descriptions in the readme.
Workaround
You can use RailsAdmin's locale feature to add a around_action to skip bullet.
https://github.com/railsadminteam/rails_admin/wiki/Base-configuration#locale
But make sure only apply to development env as bullet doesn't exist at staging/production env.
- config/initializers/rails_admin.rb
config.parent_controller = 'Admin::BaseController' if Rails.env.development
- app/controllers/admin/base_controller.rb
class Admin::BaseController < ActionController::Base
around_action :skip_bullet
private
def skip_bullet
Bullet.enable = false
yield
ensure
Bullet.enable = true
end
end