airbrake 4.3.8 → 5.0.0

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.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/lib/airbrake/capistrano/tasks.rb +64 -0
  3. data/lib/airbrake/delayed_job/plugin.rb +48 -0
  4. data/lib/airbrake/rack/middleware.rb +45 -0
  5. data/lib/airbrake/rack/notice_builder.rb +80 -0
  6. data/lib/airbrake/rack/user.rb +51 -0
  7. data/lib/airbrake/rails/action_controller.rb +35 -0
  8. data/lib/airbrake/rails/active_job.rb +23 -0
  9. data/lib/airbrake/rails/active_record.rb +40 -0
  10. data/lib/airbrake/rails/railtie.rb +61 -0
  11. data/lib/airbrake/rake/task_ext.rb +61 -0
  12. data/lib/airbrake/rake/tasks.rb +93 -0
  13. data/lib/airbrake/resque/failure.rb +19 -0
  14. data/lib/airbrake/sidekiq/error_handler.rb +35 -0
  15. data/lib/airbrake/version.rb +4 -1
  16. data/lib/airbrake.rb +16 -185
  17. data/lib/generators/airbrake_generator.rb +25 -0
  18. data/lib/generators/airbrake_initializer.rb.erb +55 -0
  19. data/spec/airbrake_spec.rb +0 -0
  20. data/spec/apps/rack/dummy_app.rb +17 -0
  21. data/spec/apps/rails/dummy_app.rb +150 -0
  22. data/spec/apps/rails/dummy_task.rake +20 -0
  23. data/spec/apps/rails/logs/32.log +13358 -0
  24. data/spec/apps/rails/logs/40.log +6854 -0
  25. data/spec/apps/rails/logs/41.log +3170 -0
  26. data/spec/apps/rails/logs/42.log +23919 -0
  27. data/spec/apps/rails/logs/50.log +10976 -0
  28. data/spec/apps/sinatra/dummy_app.rb +12 -0
  29. data/spec/integration/rack/rack_spec.rb +17 -0
  30. data/spec/integration/rails/rails_spec.rb +135 -0
  31. data/spec/integration/rails/rake_spec.rb +160 -0
  32. data/spec/integration/shared_examples/rack_examples.rb +106 -0
  33. data/spec/integration/sinatra/sinatra_spec.rb +15 -0
  34. data/spec/spec_helper.rb +127 -0
  35. data/spec/unit/rack/middleware_spec.rb +80 -0
  36. data/spec/unit/rack/notice_builder_spec.rb +35 -0
  37. data/spec/unit/rack/user_spec.rb +78 -0
  38. data/spec/unit/rake/tasks_spec.rb +40 -0
  39. data/spec/unit/sidekiq/error_handler_spec.rb +29 -0
  40. metadata +108 -323
  41. data/CHANGELOG +0 -1716
  42. data/Gemfile +0 -3
  43. data/Guardfile +0 -6
  44. data/INSTALL +0 -20
  45. data/LICENSE +0 -61
  46. data/README.md +0 -148
  47. data/README_FOR_HEROKU_ADDON.md +0 -102
  48. data/Rakefile +0 -179
  49. data/TESTED_AGAINST +0 -7
  50. data/airbrake.gemspec +0 -41
  51. data/bin/airbrake +0 -12
  52. data/features/metal.feature +0 -34
  53. data/features/rack.feature +0 -60
  54. data/features/rails.feature +0 -324
  55. data/features/rake.feature +0 -33
  56. data/features/sinatra.feature +0 -126
  57. data/features/step_definitions/file_steps.rb +0 -14
  58. data/features/step_definitions/rack_steps.rb +0 -27
  59. data/features/step_definitions/rails_application_steps.rb +0 -267
  60. data/features/step_definitions/rake_steps.rb +0 -22
  61. data/features/support/airbrake_shim.rb.template +0 -11
  62. data/features/support/aruba.rb +0 -5
  63. data/features/support/env.rb +0 -39
  64. data/features/support/matchers.rb +0 -35
  65. data/features/support/rails.rb +0 -156
  66. data/features/support/rake/Rakefile +0 -77
  67. data/features/user_informer.feature +0 -57
  68. data/generators/airbrake/airbrake_generator.rb +0 -94
  69. data/generators/airbrake/lib/insert_commands.rb +0 -34
  70. data/generators/airbrake/lib/rake_commands.rb +0 -24
  71. data/generators/airbrake/templates/airbrake_tasks.rake +0 -25
  72. data/generators/airbrake/templates/capistrano_hook.rb +0 -6
  73. data/generators/airbrake/templates/initializer.rb +0 -4
  74. data/install.rb +0 -1
  75. data/lib/airbrake/backtrace.rb +0 -103
  76. data/lib/airbrake/capistrano.rb +0 -103
  77. data/lib/airbrake/capistrano3.rb +0 -3
  78. data/lib/airbrake/cli/client.rb +0 -76
  79. data/lib/airbrake/cli/options.rb +0 -45
  80. data/lib/airbrake/cli/printer.rb +0 -33
  81. data/lib/airbrake/cli/project.rb +0 -17
  82. data/lib/airbrake/cli/project_factory.rb +0 -33
  83. data/lib/airbrake/cli/runner.rb +0 -49
  84. data/lib/airbrake/cli/validator.rb +0 -8
  85. data/lib/airbrake/configuration.rb +0 -366
  86. data/lib/airbrake/jobs/send_job.rb +0 -7
  87. data/lib/airbrake/notice.rb +0 -411
  88. data/lib/airbrake/rack.rb +0 -64
  89. data/lib/airbrake/rails/action_controller_catcher.rb +0 -32
  90. data/lib/airbrake/rails/controller_methods.rb +0 -146
  91. data/lib/airbrake/rails/error_lookup.rb +0 -35
  92. data/lib/airbrake/rails/middleware.rb +0 -63
  93. data/lib/airbrake/rails.rb +0 -45
  94. data/lib/airbrake/rails3_tasks.rb +0 -126
  95. data/lib/airbrake/railtie.rb +0 -46
  96. data/lib/airbrake/rake_handler.rb +0 -75
  97. data/lib/airbrake/response.rb +0 -29
  98. data/lib/airbrake/sender.rb +0 -213
  99. data/lib/airbrake/shared_tasks.rb +0 -59
  100. data/lib/airbrake/sidekiq.rb +0 -8
  101. data/lib/airbrake/sinatra.rb +0 -40
  102. data/lib/airbrake/tasks/airbrake.cap +0 -28
  103. data/lib/airbrake/tasks.rb +0 -81
  104. data/lib/airbrake/user_informer.rb +0 -36
  105. data/lib/airbrake/utils/params_cleaner.rb +0 -141
  106. data/lib/airbrake/utils/rack_filters.rb +0 -45
  107. data/lib/airbrake_tasks.rb +0 -62
  108. data/lib/rails/generators/airbrake/airbrake_generator.rb +0 -155
  109. data/lib/templates/rescue.erb +0 -91
  110. data/rails/init.rb +0 -1
  111. data/resources/README.md +0 -34
  112. data/resources/airbrake_2_4.xsd +0 -89
  113. data/resources/airbrake_3_0.json +0 -52
  114. data/resources/ca-bundle.crt +0 -3376
  115. data/script/integration_test.rb +0 -35
  116. data/test/airbrake_tasks_test.rb +0 -161
  117. data/test/backtrace_test.rb +0 -215
  118. data/test/capistrano_test.rb +0 -44
  119. data/test/configuration_test.rb +0 -303
  120. data/test/controller_methods_test.rb +0 -230
  121. data/test/helper.rb +0 -233
  122. data/test/integration/catcher_test.rb +0 -371
  123. data/test/integration.rb +0 -13
  124. data/test/logger_test.rb +0 -79
  125. data/test/notice_test.rb +0 -494
  126. data/test/notifier_test.rb +0 -288
  127. data/test/params_cleaner_test.rb +0 -204
  128. data/test/rack_test.rb +0 -62
  129. data/test/rails_initializer_test.rb +0 -36
  130. data/test/recursion_test.rb +0 -10
  131. data/test/response_test.rb +0 -18
  132. data/test/sender_test.rb +0 -335
  133. data/test/support/response_shim.xml +0 -4
  134. data/test/user_informer_test.rb +0 -29
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a9e654c767701024f31596525a324fd9941a284c
4
- data.tar.gz: d8beec9cd6a92be3308a4cb2cf945aaea5150eab
3
+ metadata.gz: 444112058d438d1d60afddd2d18fe604e0056c43
4
+ data.tar.gz: 275985dd0bb4949f08e7d881ac74a2ce039f1351
5
5
  SHA512:
6
- metadata.gz: e469080a0f94afeebb3be23db68c551a8ddd864b643436581f9711b7a1546f61977d80b69d9f220c56b6fe0d33e26afcb716a38d4d029ec6a8b2e810b6d52263
7
- data.tar.gz: ad08bb1d86cbd84d056bae1e55d261b3b23be3c00712eb094360e99fbfd0e5967bbc0ce2219cc45d3e8477a420bf3d44284c648768b0570b19d39a59b2dca605
6
+ metadata.gz: aff3b34806a8391c5cb917cc8cd02e3de21120cec7f04d214f5b85becbb38495b4de039e952e2f76f03990da68640fcc89549151e26bb57560039493af0eb775
7
+ data.tar.gz: 6438d408657247dbb1d6cf93cf9c77ab9d2f9e389ec64af55d6d5dd54b8311e910ca2d91d97739d86a3b9a0492421abce818919d9fe61d377b7c20f2af5078c7
@@ -0,0 +1,64 @@
1
+ require 'shellwords'
2
+ require 'fileutils'
3
+
4
+ if defined?(Capistrano::VERSION) &&
5
+ Gem::Version.new(Capistrano::VERSION).release >= Gem::Version.new('3.0.0')
6
+ namespace :airbrake do
7
+ desc "Notify Airbrake of the deploy"
8
+ task :deploy do
9
+ on roles(:all) do
10
+ within release_path do
11
+ with rails_env: fetch(:rails_env, fetch(:stage)) do
12
+ execute :rake, <<-CMD
13
+ airbrake:deploy USERNAME=#{Shellwords.shellescape(local_user)} \
14
+ ENVIRONMENT=#{fetch(:rails_env, fetch(:stage))} \
15
+ REVISION=#{fetch(:current_revision)} \
16
+ REPOSITORY=#{fetch(:repo_url)} \
17
+ VERSION=#{fetch(:app_version)}
18
+ CMD
19
+
20
+ info 'Notified Airbrake of the deploy'
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ else
27
+ module Airbrake
28
+ ##
29
+ # The Capistrano v2 integration.
30
+ module Capistrano
31
+ # rubocop:disable Metrics/AbcSize
32
+ def self.load_into(config)
33
+ config.load do
34
+ after 'deploy', 'airbrake:deploy'
35
+ after 'deploy:migrations', 'airbrake:deploy'
36
+ after 'deploy:cold', 'airbrake:deploy'
37
+
38
+ namespace :airbrake do
39
+ desc "Notify Airbrake of the deploy"
40
+ task :deploy, except: { no_release: true }, on_error: :continue do
41
+ FileUtils.cd(config.release_path) do
42
+ username = Shellwords.shellescape(ENV['USER'] || ENV['USERNAME'])
43
+
44
+ system(<<-CMD)
45
+ bundle exec rake airbrake:deploy \
46
+ USERNAME=#{username} \
47
+ ENVIRONMENT=#{fetch(:rails_env, 'production')} \
48
+ REVISION=#{current_revision.strip} \
49
+ REPOSITORY=#{repository} \
50
+ VERSION=#{fetch(:app_version, nil)}
51
+ CMD
52
+ end
53
+
54
+ logger.info 'Notified Airbrake of the deploy'
55
+ end
56
+ end
57
+ end
58
+ end
59
+ # rubocop:enable Metrics/AbcSize
60
+ end
61
+ end
62
+
63
+ Airbrake::Capistrano.load_into(Capistrano::Configuration.instance)
64
+ end
@@ -0,0 +1,48 @@
1
+ module Delayed
2
+ module Plugins
3
+ ##
4
+ # Provides integration with Delayed Job.
5
+ # rubocop:disable Lint/RescueException
6
+ class Airbrake < ::Delayed::Plugin
7
+ callbacks do |lifecycle|
8
+ lifecycle.around(:invoke_job) do |job, *args, &block|
9
+ begin
10
+ # Forward the call to the next callback in the callback chain
11
+ block.call(job, *args)
12
+ rescue Exception => exception
13
+ params = job.as_json.merge(
14
+ component: 'delayed_job',
15
+ action: job.payload_object.class.name
16
+ )
17
+
18
+ # If DelayedJob is used through ActiveJob, it contains extra info.
19
+ if job.payload_object.respond_to?(:job_data)
20
+ params[:active_job] = job.payload_object.job_data
21
+ end
22
+
23
+ ::Airbrake.notify(exception, params)
24
+ raise exception
25
+ end
26
+ end
27
+ end
28
+ end
29
+ # rubocop:enable Lint/RescueException
30
+ end
31
+ end
32
+
33
+ if RUBY_ENGINE == 'jruby' && defined?(Delayed::Backend::ActiveRecord::Job)
34
+ ##
35
+ # Workaround against JRuby bug:
36
+ # https://github.com/jruby/jruby/issues/3338
37
+ # rubocop:disable Style/ClassAndModuleChildren
38
+ class Delayed::Backend::ActiveRecord::Job
39
+ alias_method :old_to_ary, :to_ary
40
+
41
+ def to_ary
42
+ old_to_ary || [self]
43
+ end
44
+ end
45
+ # rubocop:enable Style/ClassAndModuleChildren
46
+ end
47
+
48
+ Delayed::Worker.plugins << Delayed::Plugins::Airbrake
@@ -0,0 +1,45 @@
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)
12
+ @app = app
13
+ end
14
+
15
+ ##
16
+ # Rescues any exceptions, sends them to Airbrake and re-raises the
17
+ # exception.
18
+ # @param [Hash] env the Rack environment
19
+ def call(env)
20
+ # rubocop:disable Lint/RescueException
21
+ begin
22
+ response = @app.call(env)
23
+ rescue Exception => ex
24
+ notify_airbrake(ex, env)
25
+ raise ex
26
+ end
27
+ # rubocop:enable Lint/RescueException
28
+
29
+ # The internal framework middlewares store exceptions inside the Rack
30
+ # env. See: https://goo.gl/Kd694n
31
+ exception = env['action_dispatch.exception'] || env['sinatra.error']
32
+ notify_airbrake(exception, env) if exception
33
+
34
+ response
35
+ end
36
+
37
+ private
38
+
39
+ def notify_airbrake(exception, env)
40
+ notice = NoticeBuilder.new(env).build_notice(exception)
41
+ Airbrake.notify(notice)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,80 @@
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
+ ##
8
+ # @return [String] the name of the host machine
9
+ HOSTNAME = Socket.gethostname.freeze
10
+
11
+ ##
12
+ # @param [Hash{String=>Object}] rack_env The Rack environment
13
+ def initialize(rack_env)
14
+ @rack_env = rack_env
15
+ @request = ::Rack::Request.new(rack_env)
16
+ @controller = rack_env['action_controller.instance']
17
+ @session = @request.session
18
+ @user = Airbrake::Rack::User.extract(rack_env)
19
+
20
+ @framework_version =
21
+ if defined?(::Rails)
22
+ "Rails/#{::Rails.version}"
23
+ elsif defined?(::Sinatra)
24
+ "Sinatra/#{Sinatra::VERSION}"
25
+ else
26
+ "Rack.version/#{::Rack.version} Rack.release/#{::Rack.release}"
27
+ end.freeze
28
+ end
29
+
30
+ ##
31
+ # Adds context, session, params and other fields based on the Rack env.
32
+ #
33
+ # @param [Exception] exception
34
+ # @return [Airbrake::Notice] the notice with extra information
35
+ def build_notice(exception)
36
+ notice = Airbrake.build_notice(exception)
37
+
38
+ add_context(notice)
39
+ add_session(notice)
40
+ add_params(notice)
41
+
42
+ notice
43
+ end
44
+
45
+ private
46
+
47
+ def add_context(notice)
48
+ context = notice[:context]
49
+
50
+ context[:url] = @request.url
51
+ context[:userAgent] = @request.user_agent
52
+ context[:hostname] = HOSTNAME
53
+
54
+ if context.key?(:version)
55
+ context[:version] += " #{@framework_version}"
56
+ else
57
+ context[:version] = @framework_version
58
+ end
59
+
60
+ if @controller
61
+ context[:component] = @controller.controller_name
62
+ context[:action] = @controller.action_name
63
+ end
64
+
65
+ notice[:context].merge!(@user.to_hash) if @user
66
+
67
+ nil
68
+ end
69
+
70
+ def add_session(notice)
71
+ notice[:session] = @session if @session
72
+ end
73
+
74
+ def add_params(notice)
75
+ params = @request.env['action_dispatch.request.parameters']
76
+ notice[:params] = params if params
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,51 @@
1
+ module Airbrake
2
+ module Rack
3
+ ##
4
+ # Represents an authenticated Warden user, which can be converted to
5
+ # Airbrake's payload format.
6
+ class User
7
+ # Finds the Warden user in the Rack environment and creates a new user
8
+ # wrapper.
9
+ #
10
+ # @param [Hash{String=>Object}] rack_env The Rack environment
11
+ # @return [Airbrake::Rack::User, nil]
12
+ def self.extract(rack_env)
13
+ return unless (warden = rack_env['warden'])
14
+ new(warden.user(run_callbacks: false))
15
+ end
16
+
17
+ ##
18
+ # @param [Warden::Proxy] warden_user
19
+ def initialize(warden_user)
20
+ @warden_user = warden_user
21
+ end
22
+
23
+ ##
24
+ # Converts the user to Airbrake payload user.
25
+ # @return [Hash{Symbol=>String}] the hash with retrieved user details
26
+ def to_hash
27
+ user = {}
28
+
29
+ user[:id] = try_to_get(:id)
30
+ user[:name] = full_name
31
+ user[:username] = try_to_get(:username)
32
+ user[:email] = try_to_get(:email)
33
+
34
+ user = user.delete_if { |_key, val| val.nil? }
35
+ user.empty? ? user : { user: user }
36
+ end
37
+
38
+ private
39
+
40
+ def try_to_get(key)
41
+ String(@warden_user.__send__(key)) if @warden_user.respond_to?(key)
42
+ end
43
+
44
+ def full_name
45
+ # Try to get first and last names. If that fails, try to get just 'name'.
46
+ name = [try_to_get(:first_name), try_to_get(:last_name)].compact.join(' ')
47
+ name.empty? ? try_to_get(:name) : name
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,35 @@
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
+ Airbrake.notify(build_notice(exception), parameters, notifier)
17
+ end
18
+
19
+ ##
20
+ # A helper method for sending notices to Airbrake *synchronously*.
21
+ # Attaches information from the Rack env.
22
+ # @see Airbrake#notify_sync, #notify_airbrake
23
+ def notify_airbrake_sync(exception, parameters = {}, notifier = :default)
24
+ Airbrake.notify_sync(build_notice(exception), parameters, notifier)
25
+ end
26
+
27
+ ##
28
+ # @param [Exception] exception
29
+ # @return [Airbrake::Notice] the notice with information from the Rack env
30
+ def build_notice(exception)
31
+ Airbrake::Rack::NoticeBuilder.new(request.env).build_notice(exception)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ module Airbrake
2
+ module Rails
3
+ ##
4
+ # Enables support for exceptions occurring in ActiveJob jobs.
5
+ module ActiveJob
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ rescue_from(Exception) do |exception|
10
+ notice = Airbrake.build_notice(exception)
11
+
12
+ notice[:context][:component] = self.class.name
13
+ notice[:context][:action] = job_id
14
+
15
+ notice[:params] = as_json
16
+
17
+ Airbrake.notify(notice)
18
+ raise exception
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,40 @@
1
+ module Airbrake
2
+ module Rails
3
+ ##
4
+ # Rails <4.2 has a bug with regard to swallowing exceptions in the
5
+ # +after_commit+ and the +after_rollback+ hooks: it doesn't bubble up
6
+ # exceptions from there.
7
+ #
8
+ # This module makes it possible to report exceptions occurring there.
9
+ #
10
+ # @see https://github.com/rails/rails/pull/14488 Detailed description of the
11
+ # bug and the fix
12
+ # @see https://goo.gl/348lor Rails 4.2+ implementation (fixed)
13
+ # @see https://goo.gl/ddFNg7 Rails <4.2 implementation (bugged)
14
+ module ActiveRecord
15
+ ##
16
+ # @return [Array<Symbol>] the hooks that needs fixing
17
+ KINDS = [:commit, :rollback].freeze
18
+
19
+ ##
20
+ # Patches default +run_callbacks+ with our version, which is capable of
21
+ # notifying about exceptions.
22
+ #
23
+ # rubocop:disable Lint/RescueException
24
+ def run_callbacks(kind, *args, &block)
25
+ # Let the post process handle the exception if it's not a bugged hook.
26
+ return super unless KINDS.include?(kind)
27
+
28
+ # Handle the exception ourselves. The 'ex' exception won't be
29
+ # propagated, therefore we must notify it here.
30
+ begin
31
+ super
32
+ rescue Exception => ex
33
+ Airbrake.notify(ex)
34
+ raise ex
35
+ end
36
+ end
37
+ # rubocop:enable Lint/RescueException
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,61 @@
1
+ module Airbrake
2
+ module Rails
3
+ ##
4
+ # This railtie works for any Rails application that supports railties (Rails
5
+ # 3.2+ apps). It makes Airbrake Ruby work with Rails and report errors
6
+ # occurring in the application automatically.
7
+ class Railtie < ::Rails::Railtie
8
+ initializer('airbrake.middleware') do |app|
9
+ # Since Rails 3.2 the ActionDispatch::DebugExceptions middleware is
10
+ # responsible for logging exceptions and showing a debugging page in
11
+ # case the request is local. We want to insert our middleware after
12
+ # DebugExceptions, so we don't notify Airbrake about local requests.
13
+
14
+ if ::Rails.version =~ /\A5\./
15
+ # Avoid the warning about deprecated strings.
16
+ app.config.middleware.insert_after(
17
+ ActionDispatch::DebugExceptions, Airbrake::Rack::Middleware
18
+ )
19
+ else
20
+ app.config.middleware.insert_after(
21
+ ActionDispatch::DebugExceptions, 'Airbrake::Rack::Middleware'
22
+ )
23
+ end
24
+ end
25
+
26
+ rake_tasks do
27
+ # Report exceptions occurring in Rake tasks.
28
+ require 'airbrake/rake/task_ext'
29
+
30
+ # Defines tasks such as `airbrake:test` & `airbrake:deploy`.
31
+ require 'airbrake/rake/tasks'
32
+ end
33
+
34
+ initializer('airbrake.action_controller') do
35
+ ActiveSupport.on_load(:action_controller) do
36
+ # Patches ActionController with methods that allow us to retrieve
37
+ # interesting request data. Appends that information to notices.
38
+ require 'airbrake/rails/action_controller'
39
+ include Airbrake::Rails::ActionController
40
+ end
41
+ end
42
+
43
+ initializer('airbrake.active_record') do
44
+ ActiveSupport.on_load(:active_record) do
45
+ # Reports exceptions occurring in some bugged ActiveRecord callbacks.
46
+ # Applicable only to the versions of Rails lower than 4.2.
47
+ require 'airbrake/rails/active_record'
48
+ include Airbrake::Rails::ActiveRecord
49
+ end
50
+ end
51
+
52
+ initializer('airbrake.active_job') do
53
+ ActiveSupport.on_load(:active_job) do
54
+ # Reports exceptions occurring in ActiveJob jobs.
55
+ require 'airbrake/rails/active_job'
56
+ include Airbrake::Rails::ActiveJob
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,61 @@
1
+ # This is not bulletproof, but if this file is executed before a task
2
+ # definition, we can grab tasks descriptions and locations.
3
+ # See: https://goo.gl/ksn6PE
4
+ Rake::TaskManager.record_task_metadata = true
5
+
6
+ module Rake
7
+ ##
8
+ # Redefine +Rake::Task#execute+, so it can report errors to Airbrake.
9
+ class Task
10
+ # Store the original method to use it later.
11
+ alias_method :execute_without_airbrake, :execute
12
+
13
+ ##
14
+ # A wrapper around the original +#execute+, that catches all errors and
15
+ # notifies Airbrake.
16
+ #
17
+ # rubocop:disable Lint/RescueException
18
+ def execute(args = nil)
19
+ execute_without_airbrake(args)
20
+ rescue Exception => ex
21
+ notice = Airbrake.build_notice(ex)
22
+ notice[:context][:component] = 'rake'
23
+ notice[:context][:action] = name
24
+ notice[:params] = {
25
+ rake_task: task_info,
26
+ execute_args: args,
27
+ argv: ARGV.join(' ')
28
+ }
29
+
30
+ Airbrake.notify(notice)
31
+ raise ex
32
+ end
33
+ # rubocop:enable Lint/RescueException
34
+
35
+ private
36
+
37
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
38
+ def task_info
39
+ info = {}
40
+
41
+ info[:name] = name
42
+ info[:timestamp] = timestamp.to_s
43
+ info[:investigation] = investigation
44
+
45
+ info[:full_comment] = full_comment if full_comment
46
+ info[:arg_names] = arg_names if arg_names.any?
47
+ info[:arg_description] = arg_description if arg_description
48
+ info[:locations] = locations if locations.any?
49
+ info[:sources] = sources if sources.any?
50
+
51
+ if prerequisite_tasks.any?
52
+ info[:prerequisite_tasks] = prerequisite_tasks.map do |p|
53
+ p.__send__(:task_info)
54
+ end
55
+ end
56
+
57
+ info
58
+ end
59
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize
60
+ end
61
+ end
@@ -0,0 +1,93 @@
1
+ namespace :airbrake do
2
+ desc 'Verify your gem installation by sending a test exception'
3
+ task test: :environment do
4
+ require 'pp'
5
+
6
+ begin
7
+ raise StandardError, 'Exception from the test Rake task'
8
+ rescue => ex
9
+ response = Airbrake.notify_sync(ex)
10
+ end
11
+
12
+ notifiers = Airbrake.instance_variable_get(:@notifiers).map do |name, notif|
13
+ cfg = notif.instance_variable_get(:@config)
14
+ filters = notif.instance_variable_get(:@filter_chain)
15
+ "#{name}:\n " + [cfg, filters].pretty_inspect
16
+ end.join("\n")
17
+
18
+ puts <<OUTPUT
19
+ [ruby]
20
+ description: #{RUBY_DESCRIPTION}
21
+
22
+ #{if defined?(Rails)
23
+ "[rails]\nversion: #{Rails::VERSION::STRING}"
24
+ elsif defined?(Sinatra)
25
+ "[sinatra]\nversion: #{Sinatra::VERSION}"
26
+ end}
27
+
28
+ [airbrake]
29
+ version: #{Airbrake::AIRBRAKE_VERSION}
30
+
31
+ [airbrake-ruby]
32
+ version: #{Airbrake::Notice::NOTIFIER[:version]}
33
+
34
+ [notifiers]
35
+ #{notifiers}
36
+
37
+ The output above contains useful information about your environment. Our support
38
+ team may request this information if you have problems using the Airbrake gem;
39
+ we would be really grateful if you could attach the output to your message.
40
+
41
+ The test exception was sent. Find it here: #{response['url']}
42
+ OUTPUT
43
+ end
44
+
45
+ desc 'Notify Airbrake of a new deploy'
46
+ task :deploy do
47
+ if defined?(Rails)
48
+ initializer = Rails.root.join('config', 'initializers', 'airbrake.rb')
49
+
50
+ # Avoid loading the environment to speed up the deploy task and try guess
51
+ # the initializer file location.
52
+ if initializer.exist?
53
+ load initializer
54
+ else
55
+ Rake::Task[:environment].invoke
56
+ end
57
+ end
58
+
59
+ Airbrake.create_deploy(
60
+ environment: ENV['ENVIRONMENT'],
61
+ username: ENV['USERNAME'],
62
+ revision: ENV['REVISION'],
63
+ repository: ENV['REPOSITORY'],
64
+ version: ENV['VERSION']
65
+ )
66
+ end
67
+
68
+ desc 'Install a Heroku deploy hook to notify Airbrake of deploys'
69
+ task :install_heroku_deploy_hook do
70
+ app = ENV['HEROKU_APP']
71
+
72
+ config = Bundler.with_clean_env do
73
+ `heroku config --shell#{ " --app #{app}" if app }`
74
+ end
75
+
76
+ heroku_env = config.each_line.with_object({}) do |line, h|
77
+ h.merge!(Hash[*line.rstrip.split('=')])
78
+ end
79
+
80
+ id = heroku_env['AIRBRAKE_PROJECT_ID']
81
+ key = heroku_env['AIRBRAKE_API_KEY']
82
+
83
+ exit!(1) if [id, key].any?(&:nil?)
84
+
85
+ url = "https://airbrake.io/api/v3/projects/#{id}/heroku-deploys?key=#{key}"
86
+
87
+ command = %(heroku addons:create deployhooks:http --url="#{url}")
88
+ command << " --app #{app}" if app
89
+
90
+ puts "$ #{command}"
91
+ Bundler.with_clean_env { puts `#{command}` }
92
+ end
93
+ end
@@ -0,0 +1,19 @@
1
+ module Resque
2
+ module Failure
3
+ ##
4
+ # Provides Resque integration with Airbrake.
5
+ #
6
+ # @since v5.0.0
7
+ # @see https://github.com/resque/resque/wiki/Failure-Backends
8
+ class Airbrake < Base
9
+ def save
10
+ params = payload.merge(
11
+ component: 'resque',
12
+ action: payload['class'].to_s
13
+ )
14
+
15
+ ::Airbrake.notify_sync(exception, params)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,35 @@
1
+ module Airbrake
2
+ module Sidekiq
3
+ ##
4
+ # Provides integration with Sidekiq 2 and Sidekiq 3.
5
+ class ErrorHandler
6
+ # rubocop:disable Lint/RescueException
7
+ def call(_worker, context, _queue)
8
+ yield
9
+ rescue Exception => exception
10
+ notify_airbrake(exception, context)
11
+ raise exception
12
+ end
13
+ # rubocop:enable Lint/RescueException
14
+
15
+ private
16
+
17
+ def notify_airbrake(exception, context)
18
+ params = context.merge(component: 'sidekiq', action: context['class'])
19
+ Airbrake.notify(exception, params)
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ if Sidekiq::VERSION < '3'
26
+ Sidekiq.configure_server do |config|
27
+ config.server_middleware do |chain|
28
+ chain.add(Airbrake::Sidekiq::ErrorHandler)
29
+ end
30
+ end
31
+ else
32
+ Sidekiq.configure_server do |config|
33
+ config.error_handlers << Airbrake::Sidekiq::ErrorHandler.new.method(:notify_airbrake)
34
+ end
35
+ end
@@ -1,3 +1,6 @@
1
+ ##
2
+ # We use Semantic Versioning v2.0.0
3
+ # More information: http://semver.org/
1
4
  module Airbrake
2
- VERSION = "4.3.8".freeze
5
+ AIRBRAKE_VERSION = '5.0.0'.freeze
3
6
  end