dfg-airbrake 5.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/airbrake.rb +57 -0
- data/lib/airbrake/capistrano/tasks.rb +65 -0
- data/lib/airbrake/delayed_job/plugin1.rb +52 -0
- data/lib/airbrake/rack/middleware.rb +59 -0
- data/lib/airbrake/rack/notice_builder.rb +125 -0
- data/lib/airbrake/rack/user.rb +61 -0
- data/lib/airbrake/rails/action_controller.rb +37 -0
- data/lib/airbrake/rails/active_job.rb +35 -0
- data/lib/airbrake/rails/active_record.rb +36 -0
- data/lib/airbrake/rails/railtie.rb +79 -0
- data/lib/airbrake/rake/task_ext.rb +66 -0
- data/lib/airbrake/rake/tasks.rb +118 -0
- data/lib/airbrake/resque/failure.rb +19 -0
- data/lib/airbrake/sidekiq/error_handler.rb +35 -0
- data/lib/airbrake/version.rb +6 -0
- data/lib/generators/airbrake_generator.rb +25 -0
- data/lib/generators/airbrake_initializer.rb.erb +68 -0
- data/spec/airbrake_spec.rb +17 -0
- data/spec/apps/rack/dummy_app.rb +17 -0
- data/spec/apps/rails/dummy_app.rb +156 -0
- data/spec/apps/rails/dummy_task.rake +20 -0
- data/spec/apps/sinatra/composite_app/sinatra_app1.rb +11 -0
- data/spec/apps/sinatra/composite_app/sinatra_app2.rb +11 -0
- data/spec/apps/sinatra/dummy_app.rb +12 -0
- data/spec/integration/rack/rack_spec.rb +17 -0
- data/spec/integration/rails/rails_spec.rb +216 -0
- data/spec/integration/rails/rake_spec.rb +160 -0
- data/spec/integration/shared_examples/rack_examples.rb +126 -0
- data/spec/integration/sinatra/sinatra_spec.rb +77 -0
- data/spec/spec_helper.rb +116 -0
- data/spec/unit/rack/middleware_spec.rb +136 -0
- data/spec/unit/rack/notice_builder_spec.rb +157 -0
- data/spec/unit/rack/user_spec.rb +172 -0
- data/spec/unit/rake/tasks_spec.rb +67 -0
- data/spec/unit/sidekiq/error_handler_spec.rb +33 -0
- metadata +247 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 060fe33fe27f61ec2e753fc7b3fc753b4f8fd4a7
|
|
4
|
+
data.tar.gz: 14a5b8ba79abbd1d6b19ffb053e2e04828e2a834
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d6a5aebe268567624f63f359e99b391158fc306b733c94f9e414f8755bfe164dba5fa8448671a386ba3f7799a07106d38324d53a66b96e5a0a3e482924dfa2d6
|
|
7
|
+
data.tar.gz: af44f375f3653d02d0f5a203ff8feec03dc05823bbc6e4c1c2486a023d5144677a4c927e5f1af372dc41e15bb681269d5e7ab8672feaeea492b57dfb6f99a7ea
|
data/lib/airbrake.rb
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'shellwords'
|
|
2
|
+
require 'English'
|
|
3
|
+
|
|
4
|
+
# Core library that sends notices.
|
|
5
|
+
# See: https://github.com/airbrake/airbrake-ruby
|
|
6
|
+
require 'airbrake-ruby'
|
|
7
|
+
|
|
8
|
+
require 'airbrake/version'
|
|
9
|
+
|
|
10
|
+
# Automatically load needed files for the environment the library is running in.
|
|
11
|
+
if defined?(Rack)
|
|
12
|
+
require 'airbrake/rack/user'
|
|
13
|
+
require 'airbrake/rack/notice_builder'
|
|
14
|
+
require 'airbrake/rack/middleware'
|
|
15
|
+
|
|
16
|
+
require 'airbrake/rails/railtie' if defined?(Rails)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
require 'airbrake/rake/task_ext' if defined?(Rake::Task)
|
|
20
|
+
require 'airbrake/resque/failure' if defined?(Resque)
|
|
21
|
+
require 'airbrake/sidekiq/error_handler' if defined?(Sidekiq)
|
|
22
|
+
# 2016-12-19
|
|
23
|
+
# https://meta.discourse.org/t/54462
|
|
24
|
+
# «The Plugin::Instance.find_all method incorrectly treats every file with the «plugin.rb» name
|
|
25
|
+
# as a Discourse plugin».
|
|
26
|
+
require 'airbrake/delayed_job/plugin1' if defined?(Delayed)
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# This module reopens the original Airbrake module from airbrake-ruby and adds
|
|
30
|
+
# integration specific methods.
|
|
31
|
+
module Airbrake
|
|
32
|
+
class << self
|
|
33
|
+
##
|
|
34
|
+
# Attaches a callback (builder) that runs every time the Rack integration
|
|
35
|
+
# reports an error. Can be used to attach additional data from the Rack
|
|
36
|
+
# request.
|
|
37
|
+
#
|
|
38
|
+
# @example Adding remote IP from the Rack environment
|
|
39
|
+
# Airbrake.add_rack_builder do |notice, request|
|
|
40
|
+
# notice[:params][:remoteIp] = request.env['REMOTE_IP']
|
|
41
|
+
# end
|
|
42
|
+
#
|
|
43
|
+
# @yieldparam notice [Airbrake::Notice] notice that will be sent to Airbrake
|
|
44
|
+
# @yieldparam request [Rack::Request] current rack request
|
|
45
|
+
# @yieldreturn [void]
|
|
46
|
+
# @return [void]
|
|
47
|
+
# @since 5.1.0
|
|
48
|
+
def add_rack_builder(&block)
|
|
49
|
+
Airbrake::Rack::NoticeBuilder.add_builder(&block)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Notify of unhandled exceptions, if there were any, but ignore SystemExit.
|
|
55
|
+
at_exit do
|
|
56
|
+
Airbrake.notify_sync($ERROR_INFO) if $ERROR_INFO
|
|
57
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
if defined?(Capistrano::VERSION) &&
|
|
2
|
+
Gem::Version.new(Capistrano::VERSION).release >= Gem::Version.new('3.0.0')
|
|
3
|
+
namespace :airbrake do
|
|
4
|
+
desc "Notify Airbrake of the deploy"
|
|
5
|
+
task :deploy do
|
|
6
|
+
role = roles(:all, select: :primary).first || roles(:all).first
|
|
7
|
+
on role do
|
|
8
|
+
within release_path do
|
|
9
|
+
with rails_env: fetch(:rails_env, fetch(:stage)) do
|
|
10
|
+
execute :bundle, :exec, :rake, <<-CMD
|
|
11
|
+
airbrake:deploy USERNAME=#{Shellwords.shellescape(local_user)} \
|
|
12
|
+
ENVIRONMENT=#{fetch(:airbrake_env, fetch(:rails_env, fetch(:stage)))} \
|
|
13
|
+
REVISION=#{fetch(:current_revision)} \
|
|
14
|
+
REPOSITORY=#{fetch(:repo_url)} \
|
|
15
|
+
VERSION=#{fetch(:app_version)}
|
|
16
|
+
CMD
|
|
17
|
+
|
|
18
|
+
info 'Notified Airbrake of the deploy'
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
else
|
|
25
|
+
module Airbrake
|
|
26
|
+
##
|
|
27
|
+
# The Capistrano v2 integration.
|
|
28
|
+
module Capistrano
|
|
29
|
+
# rubocop:disable Metrics/AbcSize
|
|
30
|
+
def self.load_into(config)
|
|
31
|
+
config.load do
|
|
32
|
+
after 'deploy', 'airbrake:deploy'
|
|
33
|
+
after 'deploy:migrations', 'airbrake:deploy'
|
|
34
|
+
after 'deploy:cold', 'airbrake:deploy'
|
|
35
|
+
|
|
36
|
+
namespace :airbrake do
|
|
37
|
+
desc "Notify Airbrake of the deploy"
|
|
38
|
+
task :deploy, except: { no_release: true }, on_error: :continue do
|
|
39
|
+
username = Shellwords.shellescape(ENV['USER'] || ENV['USERNAME'])
|
|
40
|
+
command = <<-CMD
|
|
41
|
+
cd #{config.release_path} && \
|
|
42
|
+
|
|
43
|
+
RACK_ENV=#{fetch(:rack_env, nil)} \
|
|
44
|
+
RAILS_ENV=#{fetch(:rails_env, nil)} \
|
|
45
|
+
|
|
46
|
+
bundle exec rake airbrake:deploy \
|
|
47
|
+
USERNAME=#{username} \
|
|
48
|
+
ENVIRONMENT=#{fetch(:rails_env, 'production')} \
|
|
49
|
+
REVISION=#{current_revision.strip} \
|
|
50
|
+
REPOSITORY=#{repository} \
|
|
51
|
+
VERSION=#{fetch(:app_version, nil)}
|
|
52
|
+
CMD
|
|
53
|
+
|
|
54
|
+
run(command, once: true)
|
|
55
|
+
logger.info 'Notified Airbrake of the deploy'
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
# rubocop:enable Metrics/AbcSize
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
Airbrake::Capistrano.load_into(Capistrano::Configuration.instance)
|
|
65
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# 2016-12-19
|
|
2
|
+
# https://meta.discourse.org/t/54462
|
|
3
|
+
# «The Plugin::Instance.find_all method incorrectly treats every file with the «plugin.rb» name
|
|
4
|
+
# as a Discourse plugin».
|
|
5
|
+
module Delayed
|
|
6
|
+
module Plugins
|
|
7
|
+
##
|
|
8
|
+
# Provides integration with Delayed Job.
|
|
9
|
+
# rubocop:disable Lint/RescueException
|
|
10
|
+
class Airbrake < ::Delayed::Plugin
|
|
11
|
+
callbacks do |lifecycle|
|
|
12
|
+
lifecycle.around(:invoke_job) do |job, *args, &block|
|
|
13
|
+
begin
|
|
14
|
+
# Forward the call to the next callback in the callback chain
|
|
15
|
+
block.call(job, *args)
|
|
16
|
+
rescue Exception => exception
|
|
17
|
+
params = job.as_json.merge(
|
|
18
|
+
component: 'delayed_job',
|
|
19
|
+
action: job.payload_object.class.name
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
# If DelayedJob is used through ActiveJob, it contains extra info.
|
|
23
|
+
if job.payload_object.respond_to?(:job_data)
|
|
24
|
+
params[:active_job] = job.payload_object.job_data
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
::Airbrake.notify(exception, params)
|
|
28
|
+
raise exception
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
# rubocop:enable Lint/RescueException
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
if RUBY_ENGINE == 'jruby' && defined?(Delayed::Backend::ActiveRecord::Job)
|
|
38
|
+
##
|
|
39
|
+
# Workaround against JRuby bug:
|
|
40
|
+
# https://github.com/jruby/jruby/issues/3338
|
|
41
|
+
# rubocop:disable Style/ClassAndModuleChildren
|
|
42
|
+
class Delayed::Backend::ActiveRecord::Job
|
|
43
|
+
alias old_to_ary to_ary
|
|
44
|
+
|
|
45
|
+
def to_ary
|
|
46
|
+
old_to_ary || [self]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
# rubocop:enable Style/ClassAndModuleChildren
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
Delayed::Worker.plugins << Delayed::Plugins::Airbrake
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Airbrake
|
|
2
|
+
module Rack
|
|
3
|
+
##
|
|
4
|
+
# Airbrake Rack middleware for Rails and Sinatra applications (or any other
|
|
5
|
+
# Rack-compliant app). Any errors raised by the upstream application will be
|
|
6
|
+
# delivered to Airbrake and re-raised.
|
|
7
|
+
#
|
|
8
|
+
# The middleware automatically sends information about the framework that
|
|
9
|
+
# uses it (name and version).
|
|
10
|
+
class Middleware
|
|
11
|
+
def initialize(app, notifier_name = :default)
|
|
12
|
+
@app = app
|
|
13
|
+
@notifier_name = notifier_name
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
# Rescues any exceptions, sends them to Airbrake and re-raises the
|
|
18
|
+
# exception.
|
|
19
|
+
# @param [Hash] env the Rack environment
|
|
20
|
+
def call(env)
|
|
21
|
+
# rubocop:disable Lint/RescueException
|
|
22
|
+
begin
|
|
23
|
+
response = @app.call(env)
|
|
24
|
+
rescue Exception => ex
|
|
25
|
+
notify_airbrake(ex, env)
|
|
26
|
+
raise ex
|
|
27
|
+
end
|
|
28
|
+
# rubocop:enable Lint/RescueException
|
|
29
|
+
|
|
30
|
+
exception = framework_exception(env)
|
|
31
|
+
notify_airbrake(exception, env) if exception
|
|
32
|
+
|
|
33
|
+
response
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def notify_airbrake(exception, env)
|
|
39
|
+
notice = NoticeBuilder.new(env, @notifier_name).build_notice(exception)
|
|
40
|
+
return unless notice
|
|
41
|
+
|
|
42
|
+
Airbrake.notify(notice, {}, @notifier_name)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Web framework middlewares often store rescued exceptions inside the
|
|
47
|
+
# Rack env, but Rack doesn't have a standard key for it:
|
|
48
|
+
#
|
|
49
|
+
# - Rails uses action_dispatch.exception: https://goo.gl/Kd694n
|
|
50
|
+
# - Sinatra uses sinatra.error: https://goo.gl/LLkVL9
|
|
51
|
+
# - Goliath uses rack.exception: https://goo.gl/i7e1nA
|
|
52
|
+
def framework_exception(env)
|
|
53
|
+
env['action_dispatch.exception'] ||
|
|
54
|
+
env['sinatra.error'] ||
|
|
55
|
+
env['rack.exception']
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
module Airbrake
|
|
2
|
+
module Rack
|
|
3
|
+
##
|
|
4
|
+
# A helper class for filling notices with all sorts of useful information
|
|
5
|
+
# coming from the Rack environment.
|
|
6
|
+
class NoticeBuilder
|
|
7
|
+
@builders = []
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
##
|
|
11
|
+
# @return [Array<Proc>] the list of notice builders
|
|
12
|
+
attr_reader :builders
|
|
13
|
+
|
|
14
|
+
##
|
|
15
|
+
# Adds user defined builders to the chain.
|
|
16
|
+
def add_builder(&block)
|
|
17
|
+
@builders << block
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# @return [Array<String>] the prefixes of the majority of HTTP headers in
|
|
23
|
+
# Rack (some prefixes match the header names for simplicity)
|
|
24
|
+
HTTP_HEADER_PREFIXES = [
|
|
25
|
+
'HTTP_'.freeze,
|
|
26
|
+
'CONTENT_TYPE'.freeze,
|
|
27
|
+
'CONTENT_LENGTH'.freeze
|
|
28
|
+
].freeze
|
|
29
|
+
|
|
30
|
+
##
|
|
31
|
+
# @param [Hash{String=>Object}] rack_env The Rack environment
|
|
32
|
+
def initialize(rack_env, notifier_name = :default)
|
|
33
|
+
@rack_env = rack_env
|
|
34
|
+
@notifier_name = notifier_name
|
|
35
|
+
@request = ::Rack::Request.new(rack_env)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
##
|
|
39
|
+
# Adds context, session, params and other fields based on the Rack env.
|
|
40
|
+
#
|
|
41
|
+
# @param [Exception] exception
|
|
42
|
+
# @return [Airbrake::Notice] the notice with extra information
|
|
43
|
+
def build_notice(exception)
|
|
44
|
+
return unless (notice = Airbrake.build_notice(exception, {}, @notifier_name))
|
|
45
|
+
|
|
46
|
+
NoticeBuilder.builders.each { |builder| builder.call(notice, @request) }
|
|
47
|
+
notice
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
##
|
|
51
|
+
# Adds context (URL, User-Agent, framework version, controller and more).
|
|
52
|
+
add_builder do |notice, request|
|
|
53
|
+
context = notice[:context]
|
|
54
|
+
|
|
55
|
+
context[:url] = request.url
|
|
56
|
+
context[:userAgent] = request.user_agent
|
|
57
|
+
|
|
58
|
+
framework_version =
|
|
59
|
+
if defined?(::Rails)
|
|
60
|
+
"Rails/#{::Rails.version}"
|
|
61
|
+
elsif defined?(::Sinatra)
|
|
62
|
+
"Sinatra/#{Sinatra::VERSION}"
|
|
63
|
+
else
|
|
64
|
+
"Rack.version/#{::Rack.version} Rack.release/#{::Rack.release}"
|
|
65
|
+
end.freeze
|
|
66
|
+
|
|
67
|
+
if context.key?(:version)
|
|
68
|
+
context[:version] += " #{framework_version}"
|
|
69
|
+
else
|
|
70
|
+
context[:version] = framework_version
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
controller = request.env['action_controller.instance']
|
|
74
|
+
if controller
|
|
75
|
+
context[:component] = controller.controller_name
|
|
76
|
+
context[:action] = controller.action_name
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
user = Airbrake::Rack::User.extract(request.env)
|
|
80
|
+
notice[:context].merge!(user.as_json) if user
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
##
|
|
84
|
+
# Adds session.
|
|
85
|
+
add_builder do |notice, request|
|
|
86
|
+
session = request.session
|
|
87
|
+
notice[:session] = session if session
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
##
|
|
91
|
+
# Adds HTTP request parameters.
|
|
92
|
+
add_builder do |notice, request|
|
|
93
|
+
notice[:params] = request.params
|
|
94
|
+
|
|
95
|
+
rails_params = request.env['action_dispatch.request.parameters']
|
|
96
|
+
notice[:params].merge!(rails_params) if rails_params
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
##
|
|
100
|
+
# Adds HTTP referer, method and headers to the environment.
|
|
101
|
+
add_builder do |notice, request|
|
|
102
|
+
http_headers = request.env.map.with_object({}) do |(key, value), headers|
|
|
103
|
+
if HTTP_HEADER_PREFIXES.any? { |prefix| key.to_s.start_with?(prefix) }
|
|
104
|
+
headers[key] = value
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
headers
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
notice[:environment].merge!(
|
|
111
|
+
httpMethod: request.request_method,
|
|
112
|
+
referer: request.referer,
|
|
113
|
+
headers: http_headers
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
if request.body
|
|
117
|
+
notice[:environment][:body] = request.body.read(4096)
|
|
118
|
+
request.body.rewind
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
notice[:environment]
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Airbrake
|
|
2
|
+
module Rack
|
|
3
|
+
##
|
|
4
|
+
# Represents an authenticated user, which can be converted to Airbrake's
|
|
5
|
+
# payload format. Supports Warden and Omniauth authentication frameworks.
|
|
6
|
+
class User
|
|
7
|
+
# Finds the user in the Rack environment and creates a new user wrapper.
|
|
8
|
+
#
|
|
9
|
+
# @param [Hash{String=>Object}] rack_env The Rack environment
|
|
10
|
+
# @return [Airbrake::Rack::User, nil]
|
|
11
|
+
def self.extract(rack_env)
|
|
12
|
+
# Warden support (including Devise).
|
|
13
|
+
if (warden = rack_env['warden'])
|
|
14
|
+
if (user = warden.user(run_callbacks: false))
|
|
15
|
+
return new(user) if user
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Fallback mode (OmniAuth support included). Works only for Rails.
|
|
20
|
+
user = try_current_user(rack_env)
|
|
21
|
+
new(user) if user
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.try_current_user(rack_env)
|
|
25
|
+
controller = rack_env['action_controller.instance']
|
|
26
|
+
return unless controller.respond_to?(:current_user)
|
|
27
|
+
return unless [-1, 0].include?(controller.method(:current_user).arity)
|
|
28
|
+
controller.current_user
|
|
29
|
+
end
|
|
30
|
+
private_class_method :try_current_user
|
|
31
|
+
|
|
32
|
+
def initialize(user)
|
|
33
|
+
@user = user
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def as_json
|
|
37
|
+
user = {}
|
|
38
|
+
|
|
39
|
+
user[:id] = try_to_get(:id)
|
|
40
|
+
user[:name] = full_name
|
|
41
|
+
user[:username] = try_to_get(:username)
|
|
42
|
+
user[:email] = try_to_get(:email)
|
|
43
|
+
|
|
44
|
+
user = user.delete_if { |_key, val| val.nil? }
|
|
45
|
+
user.empty? ? user : { user: user }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def try_to_get(key)
|
|
51
|
+
String(@user.__send__(key)) if @user.respond_to?(key)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def full_name
|
|
55
|
+
# Try to get first and last names. If that fails, try to get just 'name'.
|
|
56
|
+
name = [try_to_get(:first_name), try_to_get(:last_name)].compact.join(' ')
|
|
57
|
+
name.empty? ? try_to_get(:name) : name
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Airbrake
|
|
2
|
+
module Rails
|
|
3
|
+
##
|
|
4
|
+
# Contains helper methods that can be used inside Rails controllers to send
|
|
5
|
+
# notices to Airbrake. The main benefit of using them instead of the direct
|
|
6
|
+
# API is that they automatically add information from the Rack environment
|
|
7
|
+
# to notices.
|
|
8
|
+
module ActionController
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# A helper method for sending notices to Airbrake *asynchronously*.
|
|
13
|
+
# Attaches information from the Rack env.
|
|
14
|
+
# @see Airbrake#notify, #notify_airbrake_sync
|
|
15
|
+
def notify_airbrake(exception, parameters = {}, notifier = :default)
|
|
16
|
+
return unless (notice = build_notice(exception))
|
|
17
|
+
Airbrake.notify(notice, parameters, notifier)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# A helper method for sending notices to Airbrake *synchronously*.
|
|
22
|
+
# Attaches information from the Rack env.
|
|
23
|
+
# @see Airbrake#notify_sync, #notify_airbrake
|
|
24
|
+
def notify_airbrake_sync(exception, parameters = {}, notifier = :default)
|
|
25
|
+
return unless (notice = build_notice(exception))
|
|
26
|
+
Airbrake.notify_sync(notice, parameters, notifier)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# @param [Exception] exception
|
|
31
|
+
# @return [Airbrake::Notice] the notice with information from the Rack env
|
|
32
|
+
def build_notice(exception)
|
|
33
|
+
Airbrake::Rack::NoticeBuilder.new(request.env).build_notice(exception)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|