class Airbrake::UserInformer::Middleware

stolen from github.com/airbrake/airbrake/blob/v4.3.8/lib/airbrake/user_informer.rb

Constants

DEFAULT_PLACEHOLDER
ENV_KEY
STEPS
TIMEOUT

Public Class Methods

new(app) click to toggle source
# File lib/airbrake/user_informer.rb, line 21
def initialize(app)
  @app = app
end

Public Instance Methods

call(env) click to toggle source
# File lib/airbrake/user_informer.rb, line 25
def call(env)
  status, headers, body = @app.call(env)

  if (replacement = Airbrake.user_information) && error_id = wait_for_error(env[ENV_KEY])
    replacement = replacement.gsub(/\{\{\s*error_id\s*\}\}/, error_id.to_s)
    body = replace_placeholder(replacement, body, headers)
    headers["Error-Id"] = error_id.to_s
  end
  [status, headers, body]
end

Private Instance Methods

replace_placeholder(replacement, body, headers) click to toggle source
  • body interface is .each so we cannot use anything else

  • always call .close on the old body so it can get garbage collected if it is a File

# File lib/airbrake/user_informer.rb, line 55
def replace_placeholder(replacement, body, headers)
  new_body = []
  body.each { |chunk| new_body << chunk.gsub(Airbrake.user_information_placeholder || DEFAULT_PLACEHOLDER, replacement) }
  headers["Content-Length"] = new_body.inject(0) { |sum, x| sum + x.bytesize }.to_s
  new_body
ensure
  body.close if body && body.respond_to?(:close)
end
wait_for_error(promise) click to toggle source

wait till airbrake is done reporting … stop when it fails to report TODO: use something nicer than sleep

# File lib/airbrake/user_informer.rb, line 40
def wait_for_error(promise)
  return unless promise
  done = false
  error_id = nil
  promise.then { |notice| error_id = done = notice["id"] }
  promise.rescue { |_notice| done = true }
  STEPS.times do
    break if done
    sleep TIMEOUT / STEPS
  end
  error_id
end