Airbrake error backtrace summary

We often have an error with a few thousand occurances and want to find out which code paths caused it.

Usage
Use auth-token from settings page, not your api-key.

ruby airbrake_backtraces.rb your-account your-auth-token error-id

Output

Trace 1: occurred 597 times
...funky backtraces...
Trace 2: occurred 119 times
...funky backtraces...
Trace 3: occurred 13 times
...funky backtraces...

Code

#! /usr/bin/env ruby
# lists all sources of a given error
# https://grosser.it/2012/09/08/airbrake-error-summary
#
# gem install airbrake-api
# USAGE: ruby airbrake_backtraces.rb your-account your-auth-token error-id
# https://your-account.airbrake.io/errors/ID

require "airbrake-api"

AirbrakeAPI.account = ARGV[0] || raise("need airbrake account as ARGV[0]")
AirbrakeAPI.auth_token = ARGV[1] || raise("need airbrake token as ARGV[1], go to airbrake -> settings, copy your auth token")
AirbrakeAPI.secure = true

error_id = ARGV[2] || raise("need error id")
compare_depth = (ARGV[3] || 4).to_i

notices = AirbrakeAPI.notices(error_id, :pages => 20)
backtraces = notices.select{|n| n.backtrace }.group_by do |notice|
  notice.backtrace.first[1][0..compare_depth]
end

backtraces.sort_by{|k,t| t.size }.reverse.each_with_index do |(key, traces), index|
  puts "Trace #{index + 1}: occurred #{traces.size} times"
  puts key
  puts ""
end

Airbrake search

We need to search for specific errors quiet often, this script helps us find them without having to go through the web interface.

Usage
auth_token can be found on your settings page, it is NOT the api-key.

ruby airbrake_search.rb your-account your-auth-token | grep foo

Code

#! /usr/bin/env ruby
# https://grosser.it/2012/09/08/airbrake-search
# search for errors given a name
#
# gem install airbrake-api
# USAGE: ruby airbrake_search.rb your-account your-auth-token | grep SOMETHING
# https://your-account.airbrake.io/errors/ID

require "airbrake-api"

AirbrakeAPI.account = ARGV[0] || raise("need airbrake account as ARGV[0]")
AirbrakeAPI.auth_token = ARGV[1] || raise("need airbrake token as ARGV[1], go to airbrake -> settings, copy your auth token")
AirbrakeAPI.secure = true

page = 1
while errors = AirbrakeAPI.errors(:page => page)
  errors.each do |error|
    puts "#{error.id} -- #{error.error_class} -- #{error.error_message} -- #{error.created_at}"
  end
  $stderr.puts "Page #{page} ----------\n"
  page += 1
end

Fixing brittle tests by running them again (shoulda)

Really fixing them would be nicer but that can be complicated, so just run them 3 times and if they fail every time fail, otherwise pass with warnings.

Code


  def self.brittle_should(test, &block)
    results = []
    tries = 3

    tries.times do |i|
      should test + " (try #{i+1})" do
        if results.empty? or results.none?
          begin
            instance_exec(&block)
            results << true
          rescue Object
            if results.size < tries
              warn "Brittle test #{test.inspect} failed, trying again..."
              results << false
            else
              raise
            end
          end
        end
      end
    end
  end

Rack::Utils.escape / unescape + CGI.escape/unescape/escapeHTML vs undefined method bytesize for nil

The official solution for this problem is to use e.g. CGI.escape thing.to_str,
my unofficial solution is to automate that 🙂

Code

# https://grosser.it/2012/08/16/rackutils-escape-unescape-cgi-escapeunescapeescapehtml-vs-undefined-method-bytesize-for-nil/
AUTOMATED_TO_STR_FOR_SAFE_BUFFER = <<-RUBY
  def METHOD_with_html_safe(object)
    if object.is_a?(ActiveSupport::SafeBuffer)
      METHOD(object.to_str)
    else
      METHOD_without_html_safe(object)
    end
  end
  alias_method_chain :METHOD, :html_safe
RUBY

# can be removed if
# Rack::Utils.escape "a & & %24".html_safe
# Rack::Utils.unescape "a & & %24".html_safe
# does not raise an error, must work with strings and symbols
Rack::Utils.class_eval do
  [:escape, :unescape].each do |method|
    eval AUTOMATED_TO_STR_FOR_SAFE_BUFFER.gsub("METHOD", method.to_s)
    module_function :"#{method}_without_html_safe"
    module_function method
  end
end

# can be removed if
# CGI.escape "a & & %24".html_safe
# CGI.unescape "a & & %24".html_safe
# CGI.unescapeHTML "a & & %24".html_safe
# does not raise an error, must work with strings and symbols
# (escapeHTML always works)
CGI.class_eval do
  class << self
    [:escape, :unescape, :unescapeHTML].each do |method|
      eval AUTOMATED_TO_STR_FOR_SAFE_BUFFER.gsub("METHOD", method.to_s)
    end
  end
end

Object.send :remove_const, :AUTOMATED_TO_STR_FOR_SAFE_BUFFER

rewrite git history with git edit

I’m currently doing a lot of history rewrites to keep my branch clean (tons of changes that I rebase regularly)

So I built git-edit

Usage

git-edit abf1234
... do some work ...
git-edit --amend # amend changes to abf1234 and finish
# or if things go south ...
git-edit --abort  # get me out of here 🙂

Install
Install ruby.

curl https://raw.github.com/grosser/dotfiles/master/bin/git-edit >\
 ~/bin/git-edit && chmod +x ~/bin/git-edit

Remember: Do not use unless you are the only one working on this branch!