rollbar 2.15.0 → 2.15.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile +1 -0
- data/README.md +22 -1
- data/data/rollbar.snippet.js +1 -1
- data/lib/generators/rollbar/templates/initializer.rb +1 -1
- data/lib/rollbar/configuration.rb +6 -0
- data/lib/rollbar/delay/shoryuken.rb +29 -0
- data/lib/rollbar/middleware/js.rb +1 -0
- data/lib/rollbar/plugins/delayed_job/job_data.rb +2 -0
- data/lib/rollbar/plugins/delayed_job/plugin.rb +3 -0
- data/lib/rollbar/plugins/sidekiq/plugin.rb +9 -9
- data/lib/rollbar/version.rb +1 -1
- data/spec/rollbar/middleware/js_spec.rb +19 -3
- data/spec/rollbar/plugins/delayed_job_spec.rb +13 -0
- data/spec/rollbar/plugins/sidekiq_spec.rb +92 -60
- data/spec/rollbar_spec.rb +15 -0
- metadata +13 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73754e6a1e6bf9d7914571a174c10265cd0d85fa
|
4
|
+
data.tar.gz: 8c1f3715b20d672299b4be4a1fdbd8cc7fd7a602
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 702e9699419e0877522940dc1b6fe782c8d73dbb118f38b80dfb566e9f3db070fa3f8ccb244313d90c0d3e813c032fbc06d5f4cc9815be1fe47710725fc07b46
|
7
|
+
data.tar.gz: a077c1f297ea59b496ad9f172e8aafc900fe91971f44fd4f42ddb23675e1554352dbf563f99a5b8c2f0fa1e36a5599cbc9a591f36f6fe2400a92ad7ca0e303d0
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 2.15.1
|
4
|
+
|
5
|
+
- Update rollbar.js to v2.2.3 [#630](https://github.com/rollbar/rollbar-gem/pull/630)
|
6
|
+
- allow csp opt out [#629](https://github.com/rollbar/rollbar-gem/pull/629)
|
7
|
+
- Fix: [#472](https://github.com/rollbar/rollbar-gem/issues/472)
|
8
|
+
- Ignore empty ROLLBAR_ENV [#604](https://github.com/rollbar/rollbar-gem/pull/604)
|
9
|
+
- Shoryuken gem support [#576](https://github.com/rollbar/rollbar-gem/pull/576)
|
10
|
+
- support new sidekiq context structure [#598](https://github.com/rollbar/rollbar-gem/pull/598)
|
11
|
+
|
3
12
|
## 2.15.0
|
4
13
|
|
5
14
|
Features:
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Rollbar [![Build Status](https://api.travis-ci.org/rollbar/rollbar-gem.svg?branch=v2.15.
|
1
|
+
# Rollbar [![Build Status](https://api.travis-ci.org/rollbar/rollbar-gem.svg?branch=v2.15.1)](https://travis-ci.org/rollbar/rollbar-gem/branches)
|
2
2
|
|
3
3
|
<!-- RemoveNext -->
|
4
4
|
[Rollbar](https://rollbar.com) is an error tracking service for Ruby and other languages. The Rollbar service will alert you of problems with your code and help you understand them in a ways never possible before. We love it and we hope you will too.
|
@@ -763,6 +763,27 @@ For every errored job a new report will be sent to Rollbar API, also for errored
|
|
763
763
|
config.sidekiq_threshold = 3 # Start reporting from 3 retries jobs
|
764
764
|
```
|
765
765
|
|
766
|
+
### Shoryuken
|
767
|
+
|
768
|
+
Add the following in ```config/initializers/rollbar.rb```
|
769
|
+
|
770
|
+
```ruby
|
771
|
+
config.environment = Rails.env # necessary for building proper SQS name.
|
772
|
+
config.use_shoryuken
|
773
|
+
```
|
774
|
+
|
775
|
+
You also need to have the configuration for shoryuken in you project `shoryuken.yml` and AWS settings, or, at least:
|
776
|
+
```ruby
|
777
|
+
ENV['AWS_ACCESS_KEY_ID'] = 'xxx'
|
778
|
+
ENV['AWS_SECRET_ACCESS_KEY'] = 'xxx'
|
779
|
+
ENV['AWS_REGION'] = 'xxx'
|
780
|
+
```
|
781
|
+
Read more about [Shoryuken configuration]https://github.com/phstc/shoryuken/wiki/Shoryuken-options
|
782
|
+
|
783
|
+
Also create the SQS channels equals to your environments, as follows:
|
784
|
+
The queues to report will be equal to ```rollbar_{CURRENT_ENVIRONMENT}``` ex: if the project runs in staging environment the SQS to throw messages to will be equal to ```rollbar_staging```
|
785
|
+
At this stage, you are unable to set custom SQS name to use.
|
786
|
+
|
766
787
|
### Resque
|
767
788
|
|
768
789
|
Add the following in ```config/initializers/rollbar.rb```:
|
data/data/rollbar.snippet.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
!function(r){function o(
|
1
|
+
!function(r){function o(n){if(e[n])return e[n].exports;var t=e[n]={exports:{},id:n,loaded:!1};return r[n].call(t.exports,t,t.exports,o),t.loaded=!0,t.exports}var e={};return o.m=r,o.c=e,o.p="",o(0)}([function(r,o,e){"use strict";var n=e(1),t=e(4);_rollbarConfig=_rollbarConfig||{},_rollbarConfig.rollbarJsUrl=_rollbarConfig.rollbarJsUrl||"https://cdnjs.cloudflare.com/ajax/libs/rollbar.js/2.2.3/rollbar.min.js",_rollbarConfig.async=void 0===_rollbarConfig.async||_rollbarConfig.async;var a=n.setupShim(window,_rollbarConfig),l=t(_rollbarConfig);window.rollbar=n.Rollbar,a.loadFull(window,document,!_rollbarConfig.async,_rollbarConfig,l)},function(r,o,e){"use strict";function n(r){return function(){try{return r.apply(this,arguments)}catch(r){try{console.error("[Rollbar]: Internal error",r)}catch(r){}}}}function t(r,o){this.options=r,this._rollbarOldOnError=null;var e=s++;this.shimId=function(){return e},window&&window._rollbarShims&&(window._rollbarShims[e]={handler:o,messages:[]})}function a(r,o){var e=o.globalAlias||"Rollbar";if("object"==typeof r[e])return r[e];r._rollbarShims={},r._rollbarWrappedError=null;var t=new p(o);return n(function(){o.captureUncaught&&(t._rollbarOldOnError=r.onerror,i.captureUncaughtExceptions(r,t,!0),i.wrapGlobals(r,t,!0)),o.captureUnhandledRejections&&i.captureUnhandledRejections(r,t,!0);var n=o.autoInstrument;return(void 0===n||n===!0||"object"==typeof n&&n.network)&&r.addEventListener&&(r.addEventListener("load",t.captureLoad.bind(t)),r.addEventListener("DOMContentLoaded",t.captureDomContentLoaded.bind(t))),r[e]=t,t})()}function l(r){return n(function(){var o=this,e=Array.prototype.slice.call(arguments,0),n={shim:o,method:r,args:e,ts:new Date};window._rollbarShims[this.shimId()].messages.push(n)})}var i=e(2),s=0,d=e(3),c=function(r,o){return new t(r,o)},p=d.bind(null,c);t.prototype.loadFull=function(r,o,e,t,a){var l=function(){var o;if(void 0===r._rollbarDidLoad){o=new Error("rollbar.js did not load");for(var e,n,t,l,i=0;e=r._rollbarShims[i++];)for(e=e.messages||[];n=e.shift();)for(t=n.args||[],i=0;i<t.length;++i)if(l=t[i],"function"==typeof l){l(o);break}}"function"==typeof a&&a(o)},i=!1,s=o.createElement("script"),d=o.getElementsByTagName("script")[0],c=d.parentNode;s.crossOrigin="",s.src=t.rollbarJsUrl,e||(s.async=!0),s.onload=s.onreadystatechange=n(function(){if(!(i||this.readyState&&"loaded"!==this.readyState&&"complete"!==this.readyState)){s.onload=s.onreadystatechange=null;try{c.removeChild(s)}catch(r){}i=!0,l()}}),c.insertBefore(s,d)},t.prototype.wrap=function(r,o,e){try{var n;if(n="function"==typeof o?o:function(){return o||{}},"function"!=typeof r)return r;if(r._isWrap)return r;if(!r._rollbar_wrapped&&(r._rollbar_wrapped=function(){e&&"function"==typeof e&&e.apply(this,arguments);try{return r.apply(this,arguments)}catch(e){var o=e;throw"string"==typeof o&&(o=new String(o)),o._rollbarContext=n()||{},o._rollbarContext._wrappedSource=r.toString(),window._rollbarWrappedError=o,o}},r._rollbar_wrapped._isWrap=!0,r.hasOwnProperty))for(var t in r)r.hasOwnProperty(t)&&(r._rollbar_wrapped[t]=r[t]);return r._rollbar_wrapped}catch(o){return r}};for(var u="log,debug,info,warn,warning,error,critical,global,configure,handleUncaughtException,handleUnhandledRejection,captureDomContentLoaded,captureLoad".split(","),f=0;f<u.length;++f)t.prototype[u[f]]=l(u[f]);r.exports={setupShim:a,Rollbar:p}},function(r,o){"use strict";function e(r,o,e){if(r){var t;"function"==typeof o._rollbarOldOnError?t=o._rollbarOldOnError:r.onerror&&!r.onerror.belongsToShim&&(t=r.onerror,o._rollbarOldOnError=t);var a=function(){var e=Array.prototype.slice.call(arguments,0);n(r,o,t,e)};a.belongsToShim=e,r.onerror=a}}function n(r,o,e,n){r._rollbarWrappedError&&(n[4]||(n[4]=r._rollbarWrappedError),n[5]||(n[5]=r._rollbarWrappedError._rollbarContext),r._rollbarWrappedError=null),o.handleUncaughtException.apply(o,n),e&&e.apply(r,n)}function t(r,o,e){if(r){"function"==typeof r._rollbarURH&&r._rollbarURH.belongsToShim&&r.removeEventListener("unhandledrejection",r._rollbarURH);var n=function(r){var e=r.reason,n=r.promise,t=r.detail;!e&&t&&(e=t.reason,n=t.promise),o&&o.handleUnhandledRejection&&o.handleUnhandledRejection(e,n)};n.belongsToShim=e,r._rollbarURH=n,r.addEventListener("unhandledrejection",n)}}function a(r,o,e){if(r){var n,t,a="EventTarget,Window,Node,ApplicationCache,AudioTrackList,ChannelMergerNode,CryptoOperation,EventSource,FileReader,HTMLUnknownElement,IDBDatabase,IDBRequest,IDBTransaction,KeyOperation,MediaController,MessagePort,ModalWindow,Notification,SVGElementInstance,Screen,TextTrack,TextTrackCue,TextTrackList,WebSocket,WebSocketWorker,Worker,XMLHttpRequest,XMLHttpRequestEventTarget,XMLHttpRequestUpload".split(",");for(n=0;n<a.length;++n)t=a[n],r[t]&&r[t].prototype&&l(o,r[t].prototype,e)}}function l(r,o,e){if(o.hasOwnProperty&&o.hasOwnProperty("addEventListener")){for(var n=o.addEventListener;n._rollbarOldAdd&&n.belongsToShim;)n=n._rollbarOldAdd;var t=function(o,e,t){n.call(this,o,r.wrap(e),t)};t._rollbarOldAdd=n,t.belongsToShim=e,o.addEventListener=t;for(var a=o.removeEventListener;a._rollbarOldRemove&&a.belongsToShim;)a=a._rollbarOldRemove;var l=function(r,o,e){a.call(this,r,o&&o._rollbar_wrapped||o,e)};l._rollbarOldRemove=a,l.belongsToShim=e,o.removeEventListener=l}}r.exports={captureUncaughtExceptions:e,captureUnhandledRejections:t,wrapGlobals:a}},function(r,o){"use strict";function e(r,o){this.impl=r(o,this),this.options=o,n(e.prototype)}function n(r){for(var o=function(r){return function(){var o=Array.prototype.slice.call(arguments,0);if(this.impl[r])return this.impl[r].apply(this.impl,o)}},e="log,debug,info,warn,warning,error,critical,global,configure,handleUncaughtException,handleUnhandledRejection,_createItem,wrap,loadFull,shimId,captureDomContentLoaded,captureLoad".split(","),n=0;n<e.length;n++)r[e[n]]=o(e[n])}e.prototype._swapAndProcessMessages=function(r,o){this.impl=r(this.options);for(var e,n,t;e=o.shift();)n=e.method,t=e.args,this[n]&&"function"==typeof this[n]&&("captureDomContentLoaded"===n||"captureLoad"===n?this[n].apply(this,[t[0],e.ts]):this[n].apply(this,t));return this},r.exports=e},function(r,o){"use strict";r.exports=function(r){return function(o){if(!o&&!window._rollbarInitialized){r=r||{};for(var e,n,t=r.globalAlias||"Rollbar",a=window.rollbar,l=function(r){return new a(r)},i=0;e=window._rollbarShims[i++];)n||(n=e.handler),e.handler._swapAndProcessMessages(l,e.messages);window[t]=n,window._rollbarInitialized=!0}}}}]);
|
@@ -62,5 +62,5 @@ Rollbar.configure do |config|
|
|
62
62
|
# environment variable like this: `ROLLBAR_ENV=staging`. This is a recommended
|
63
63
|
# setup for Heroku. See:
|
64
64
|
# https://devcenter.heroku.com/articles/deploying-to-a-custom-rails-environment
|
65
|
-
config.environment = ENV['ROLLBAR_ENV'] || Rails.env
|
65
|
+
config.environment = ENV['ROLLBAR_ENV'].presence || Rails.env
|
66
66
|
end
|
@@ -171,6 +171,12 @@ module Rollbar
|
|
171
171
|
@async_handler = Rollbar::Delay::Resque
|
172
172
|
end
|
173
173
|
|
174
|
+
def use_shoryuken
|
175
|
+
require 'rollbar/delay/shoryuken' if defined?(Shoryuken)
|
176
|
+
@use_async = true
|
177
|
+
@async_handler = Rollbar::Delay::Shoryuken
|
178
|
+
end
|
179
|
+
|
174
180
|
def use_sidekiq=(value)
|
175
181
|
deprecation_message = '#use_sidekiq=(value) has been deprecated in favor of #use_sidekiq(options = {}). Please update your rollbar configuration.'
|
176
182
|
defined?(ActiveSupport) ? ActiveSupport::Deprecation.warn(deprecation_message) : puts(deprecation_message)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'shoryuken'
|
2
|
+
|
3
|
+
module Rollbar
|
4
|
+
module Delay
|
5
|
+
# Following class allows to send rollbars using Sho-ryu-ken as a background jobs processor.
|
6
|
+
# see the queue_name method which states that your queues needs to be names as "rollbar_ENVIRONMENT".
|
7
|
+
# retry intervals will be used to retry sending the same message again if failed before.
|
8
|
+
class Shoryuken
|
9
|
+
include ::Shoryuken::Worker
|
10
|
+
|
11
|
+
# not allowing bulk, to not double-report rollbars if one of them failed in bunch.
|
12
|
+
shoryuken_options :queue => queue_name, :auto_delete => true, :body_parser => :json, :retry_intervals => [60, 180, 360, 120_0, 360_0, 186_00]
|
13
|
+
|
14
|
+
def self.queue_name
|
15
|
+
"rollbar_#{Rollbar.configuration.environment}"
|
16
|
+
end
|
17
|
+
|
18
|
+
## responsible for performing job. - payload is a json parsed body of the message.
|
19
|
+
def perform(_sqs_message, payload)
|
20
|
+
Rollbar.process_from_async_handler(payload)
|
21
|
+
end
|
22
|
+
|
23
|
+
## to push the job !
|
24
|
+
def call(payload)
|
25
|
+
self.class.perform_async(payload)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -150,6 +150,7 @@ module Rollbar
|
|
150
150
|
def append_nonce?
|
151
151
|
defined?(::SecureHeaders) && ::SecureHeaders.respond_to?(:content_security_policy_script_nonce) &&
|
152
152
|
defined?(::SecureHeaders::Configuration) &&
|
153
|
+
!::SecureHeaders::Configuration.get.csp.opt_out? &&
|
153
154
|
!::SecureHeaders::Configuration.get.current_csp[:script_src].to_a.include?("'unsafe-inline'")
|
154
155
|
end
|
155
156
|
end
|
@@ -10,6 +10,9 @@ module Rollbar
|
|
10
10
|
class RollbarPlugin < ::Delayed::Plugin
|
11
11
|
callbacks do |lifecycle|
|
12
12
|
lifecycle.around(:invoke_job, &Delayed::invoke_job_callback)
|
13
|
+
lifecycle.after(:failure) do |_, job, _, _|
|
14
|
+
Delayed.report(job.last_error, job)
|
15
|
+
end
|
13
16
|
end
|
14
17
|
end
|
15
18
|
|
@@ -12,16 +12,16 @@ module Rollbar
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
def self.handle_exception(
|
16
|
-
|
15
|
+
def self.handle_exception(ctx_hash, e)
|
16
|
+
job_hash = ctx_hash && (ctx_hash[:job] || ctx_hash)
|
17
|
+
return if skip_report?(job_hash, e)
|
17
18
|
|
18
|
-
params = msg_or_context.reject{ |k| PARAM_BLACKLIST.include?(k) }
|
19
|
-
scrubbed_params = scrub_params(params)
|
20
19
|
scope = {
|
21
|
-
:request => { :params => scrubbed_params },
|
22
20
|
:framework => "Sidekiq: #{::Sidekiq::VERSION}"
|
23
21
|
}
|
24
|
-
|
22
|
+
unless job_hash.nil?
|
23
|
+
params = job_hash.reject { |k| PARAM_BLACKLIST.include?(k) }
|
24
|
+
scope[:request] = { :params => scrub_params(params) }
|
25
25
|
scope[:context] = params['class']
|
26
26
|
scope[:queue] = params['queue']
|
27
27
|
end
|
@@ -38,9 +38,9 @@ module Rollbar
|
|
38
38
|
Rollbar::Scrubbers::Params.call(options)
|
39
39
|
end
|
40
40
|
|
41
|
-
def self.skip_report?(
|
42
|
-
|
43
|
-
|
41
|
+
def self.skip_report?(job_hash, e)
|
42
|
+
!job_hash.nil? && (job_hash['retry'] && job_hash['retry_count'] &&
|
43
|
+
job_hash['retry_count'] < ::Rollbar.configuration.sidekiq_threshold)
|
44
44
|
end
|
45
45
|
|
46
46
|
def call(worker, msg, queue)
|
data/lib/rollbar/version.rb
CHANGED
@@ -119,7 +119,7 @@ END
|
|
119
119
|
end
|
120
120
|
|
121
121
|
it 'renders the snippet and config in the response with nonce in script tag when SecureHeaders installed' do
|
122
|
-
secure_headers_config = double(:configuration, :current_csp => {})
|
122
|
+
secure_headers_config = double(:configuration, :current_csp => {}, :csp => double(:opt_out? => false))
|
123
123
|
allow(SecureHeaders::Configuration).to receive(:get).and_return(secure_headers_config)
|
124
124
|
res_status, res_headers, response = subject.call(env)
|
125
125
|
|
@@ -131,9 +131,25 @@ END
|
|
131
131
|
end
|
132
132
|
|
133
133
|
it 'renders the snippet in the response without nonce if SecureHeaders script_src includes \'unsafe-inline\'' do
|
134
|
-
secure_headers_config = double(:configuration,
|
134
|
+
secure_headers_config = double(:configuration,
|
135
|
+
:current_csp => {
|
135
136
|
:script_src => %w('unsafe-inline')
|
136
|
-
}
|
137
|
+
},
|
138
|
+
:csp => double(:opt_out? => false))
|
139
|
+
allow(SecureHeaders::Configuration).to receive(:get).and_return(secure_headers_config)
|
140
|
+
|
141
|
+
res_status, res_headers, response = subject.call(env)
|
142
|
+
new_body = response.body.join
|
143
|
+
|
144
|
+
expect(new_body).to include('<script type="text/javascript">')
|
145
|
+
expect(new_body).to include("var _rollbarConfig = #{config[:options].to_json};")
|
146
|
+
expect(new_body).to include(snippet)
|
147
|
+
|
148
|
+
SecureHeaders.send(:remove_const, 'Configuration')
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'renders the snippet in the response without nonce if SecureHeaders CSP is OptOut' do
|
152
|
+
secure_headers_config = double(:configuration, :csp => double(:opt_out? => true))
|
137
153
|
allow(SecureHeaders::Configuration).to receive(:get).and_return(secure_headers_config)
|
138
154
|
|
139
155
|
res_status, res_headers, response = subject.call(env)
|
@@ -34,6 +34,19 @@ describe Rollbar::Delayed, :reconfigure_notifier => true do
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
+
context 'with failed deserialization' do
|
38
|
+
let(:expected_args) do
|
39
|
+
[/Delayed::DeserializationError/, {:use_exception_level_filters=>true}]
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'sends the exception' do
|
43
|
+
expect(Rollbar).to receive(:scope).with(kind_of(Hash)).and_call_original
|
44
|
+
allow_any_instance_of(Delayed::Backend::Base).to receive(:payload_object).and_raise(Delayed::DeserializationError)
|
45
|
+
expect_any_instance_of(Rollbar::Notifier).to receive(:error).with(*expected_args)
|
46
|
+
|
47
|
+
FailingJob.new.delay.do_job_please!(:foo, :bar)
|
48
|
+
end
|
49
|
+
end
|
37
50
|
|
38
51
|
describe '.build_job_data' do
|
39
52
|
let(:job) { double(:payload_object => {}) }
|
@@ -1,83 +1,111 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
unless RUBY_VERSION == '1.8.7'
|
4
|
-
require 'sidekiq'
|
5
|
-
end
|
3
|
+
require 'sidekiq' unless RUBY_VERSION == '1.8.7'
|
6
4
|
|
7
5
|
Rollbar.plugins.load!
|
8
6
|
|
9
7
|
describe Rollbar::Sidekiq, :reconfigure_notifier => false do
|
10
8
|
describe '.handle_exception' do
|
11
|
-
let(:msg_or_context) { ['hello', 'error_backtrace', 'backtrace', 'goodbye'] }
|
12
9
|
let(:exception) { StandardError.new('oh noes') }
|
13
10
|
let(:rollbar) { double }
|
14
|
-
|
11
|
+
|
12
|
+
let(:job_hash) do
|
15
13
|
{
|
16
|
-
|
17
|
-
|
14
|
+
'class' => 'FooWorker',
|
15
|
+
'args' => %w(foo bar),
|
16
|
+
'queue' => 'default',
|
17
|
+
'jid' => '96aa59723946616dff537e97',
|
18
|
+
'enqueued_at' => Time.now.to_f,
|
19
|
+
'error_message' => exception.message,
|
20
|
+
'error_class' => exception.class,
|
21
|
+
'created_at' => Time.now.to_f,
|
22
|
+
'failed_at' => Time.now.to_f,
|
23
|
+
'retry' => 3,
|
24
|
+
'retry_count' => 0
|
18
25
|
}
|
19
26
|
end
|
20
27
|
|
21
|
-
|
28
|
+
let(:ctx_hash) do
|
29
|
+
{ :context => 'Job raised exception', :job => job_hash }
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:expected_scope) do
|
33
|
+
{
|
34
|
+
:request => {
|
35
|
+
:params => job_hash.reject { |k| described_class::PARAM_BLACKLIST.include?(k) }
|
36
|
+
},
|
37
|
+
:framework => "Sidekiq: #{Sidekiq::VERSION}",
|
38
|
+
:context => job_hash['class'],
|
39
|
+
:queue => job_hash['queue']
|
40
|
+
}
|
41
|
+
end
|
22
42
|
|
23
|
-
it 'constructs scope from
|
43
|
+
it 'constructs scope from ctx hash' do
|
24
44
|
allow(rollbar).to receive(:error)
|
25
|
-
expect(Rollbar).to receive(:scope).with(
|
45
|
+
expect(Rollbar).to receive(:scope).with(expected_scope) { rollbar }
|
46
|
+
|
47
|
+
described_class.handle_exception(ctx_hash, exception)
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'sidekiq < 4.2.3 ctx hash' do
|
51
|
+
let(:ctx_hash) { job_hash }
|
52
|
+
|
53
|
+
it 'constructs scope from ctx hash' do
|
54
|
+
allow(rollbar).to receive(:error)
|
55
|
+
expect(Rollbar).to receive(:scope).with(expected_scope) { rollbar }
|
56
|
+
|
57
|
+
described_class.handle_exception(ctx_hash, exception)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'sidekiq < 4.0.0 nil ctx hash from Launcher#actor_died' do
|
62
|
+
let(:ctx_hash) { nil }
|
63
|
+
|
64
|
+
it 'constructs scope from ctx hash' do
|
65
|
+
allow(rollbar).to receive(:error)
|
66
|
+
expect(Rollbar).to receive(:scope).with(
|
67
|
+
:framework => "Sidekiq: #{Sidekiq::VERSION}"
|
68
|
+
) { rollbar }
|
26
69
|
|
27
|
-
|
70
|
+
described_class.handle_exception(ctx_hash, exception)
|
71
|
+
end
|
28
72
|
end
|
29
73
|
|
30
74
|
it 'sends the passed-in error to rollbar' do
|
31
75
|
allow(Rollbar).to receive(:scope).and_return(rollbar)
|
32
76
|
expect(rollbar).to receive(:error).with(exception, :use_exception_level_filters => true)
|
33
77
|
|
34
|
-
described_class.handle_exception(
|
78
|
+
described_class.handle_exception(ctx_hash, exception)
|
35
79
|
end
|
36
80
|
|
37
|
-
context 'with fields in
|
38
|
-
let(:
|
39
|
-
{
|
40
|
-
:foo => 'bar',
|
41
|
-
:secret => 'foo',
|
42
|
-
:password => 'foo',
|
43
|
-
:password_confirmation => 'foo'
|
44
|
-
}
|
45
|
-
end
|
46
|
-
let(:expected_params) do
|
81
|
+
context 'with fields in job hash to be scrubbed' do
|
82
|
+
let(:ctx_hash) do
|
47
83
|
{
|
48
|
-
:
|
49
|
-
:
|
50
|
-
|
51
|
-
|
84
|
+
:context => 'Job raised exception',
|
85
|
+
:job => job_hash.merge(
|
86
|
+
'foo' => 'bar',
|
87
|
+
'secret' => 'foo',
|
88
|
+
'password' => 'foo',
|
89
|
+
'password_confirmation' => 'foo'
|
90
|
+
)
|
52
91
|
}
|
53
92
|
end
|
54
93
|
|
55
94
|
before { reconfigure_notifier }
|
56
95
|
|
57
96
|
it 'sends a report with the scrubbed fields' do
|
58
|
-
described_class.handle_exception(
|
59
|
-
|
60
|
-
expect(Rollbar.last_report[:request][:params]).to be_eql_hash_with_regexes(
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
msg_or_context = {"retry" => true, "retry_count" => 1, 'queue' => 'default', 'class' => 'MyWorkerClass'}
|
67
|
-
expected_args = {
|
68
|
-
:request => { :params => msg_or_context },
|
69
|
-
:framework => "Sidekiq: #{Sidekiq::VERSION}",
|
70
|
-
:context => 'MyWorkerClass',
|
71
|
-
:queue => 'default'
|
72
|
-
}
|
73
|
-
|
74
|
-
allow(rollbar).to receive(:error)
|
75
|
-
allow(Rollbar).to receive(:scope).with(expected_args).and_return(rollbar)
|
76
|
-
described_class.handle_exception(msg_or_context, exception)
|
97
|
+
described_class.handle_exception(ctx_hash, exception)
|
98
|
+
|
99
|
+
expect(Rollbar.last_report[:request][:params]).to be_eql_hash_with_regexes(
|
100
|
+
'foo' => 'bar',
|
101
|
+
'secret' => /\*+/,
|
102
|
+
'password' => /\*+/,
|
103
|
+
'password_confirmation' => /\*+/
|
104
|
+
)
|
77
105
|
end
|
78
106
|
end
|
79
107
|
|
80
|
-
context '
|
108
|
+
context 'with a sidekiq_threshold set' do
|
81
109
|
before do
|
82
110
|
Rollbar.configuration.sidekiq_threshold = 2
|
83
111
|
end
|
@@ -86,38 +114,42 @@ describe Rollbar::Sidekiq, :reconfigure_notifier => false do
|
|
86
114
|
allow(Rollbar).to receive(:scope).and_return(rollbar)
|
87
115
|
expect(rollbar).to receive(:error).never
|
88
116
|
|
89
|
-
|
90
|
-
|
91
|
-
|
117
|
+
described_class.handle_exception(
|
118
|
+
{ :job => { 'retry' => true, 'retry_count' => 1 } },
|
119
|
+
exception
|
120
|
+
)
|
92
121
|
end
|
93
122
|
|
94
123
|
it 'sends the error to rollbar above the threshold' do
|
95
124
|
allow(Rollbar).to receive(:scope).and_return(rollbar)
|
96
125
|
expect(rollbar).to receive(:error)
|
97
126
|
|
98
|
-
|
99
|
-
|
100
|
-
|
127
|
+
described_class.handle_exception(
|
128
|
+
{ :job => { 'retry' => true, 'retry_count' => 2 } },
|
129
|
+
exception
|
130
|
+
)
|
101
131
|
end
|
102
132
|
|
103
133
|
it 'sends the error to rollbar if not retry' do
|
104
134
|
allow(Rollbar).to receive(:scope).and_return(rollbar)
|
105
135
|
expect(rollbar).to receive(:error)
|
106
136
|
|
107
|
-
|
108
|
-
|
109
|
-
|
137
|
+
described_class.handle_exception(
|
138
|
+
{ :job => { 'retry' => false } },
|
139
|
+
exception
|
140
|
+
)
|
110
141
|
end
|
111
142
|
|
112
143
|
it 'does not blow up and sends the error to rollbar if retry is true but there is no retry count' do
|
113
144
|
allow(Rollbar).to receive(:scope).and_return(rollbar)
|
114
145
|
expect(rollbar).to receive(:error)
|
115
146
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
147
|
+
expect do
|
148
|
+
described_class.handle_exception(
|
149
|
+
{ :job => { 'retry' => true } },
|
150
|
+
exception
|
151
|
+
)
|
152
|
+
end.to_not raise_error
|
121
153
|
end
|
122
154
|
end
|
123
155
|
end
|
data/spec/rollbar_spec.rb
CHANGED
@@ -20,6 +20,11 @@ begin
|
|
20
20
|
rescue LoadError
|
21
21
|
end
|
22
22
|
|
23
|
+
begin
|
24
|
+
require 'rollbar/delay/shoryuken'
|
25
|
+
rescue LoadError
|
26
|
+
end
|
27
|
+
|
23
28
|
require 'spec_helper'
|
24
29
|
|
25
30
|
describe Rollbar do
|
@@ -1173,6 +1178,16 @@ describe Rollbar do
|
|
1173
1178
|
end
|
1174
1179
|
end
|
1175
1180
|
|
1181
|
+
describe "#use_shoryuken", :if => defined?(Shoryuken) do
|
1182
|
+
it "should send the payload to shoryuken delayer" do
|
1183
|
+
logger_mock.should_receive(:info).with('[Rollbar] Scheduling item')
|
1184
|
+
expect(Rollbar::Delay::Shoryuken).to receive(:call)
|
1185
|
+
|
1186
|
+
Rollbar.configure(&:use_shoryuken)
|
1187
|
+
Rollbar.error(exception)
|
1188
|
+
end
|
1189
|
+
end
|
1190
|
+
|
1176
1191
|
describe "#use_sidekiq", :if => defined?(Sidekiq) do
|
1177
1192
|
it "should instanciate sidekiq delayer with custom values" do
|
1178
1193
|
Rollbar::Delay::Sidekiq.should_receive(:new).with('queue' => 'test_queue')
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rollbar
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.15.
|
4
|
+
version: 2.15.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rollbar, Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - '>='
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - '>='
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
description: Easy and powerful exception tracking for Ruby
|
@@ -32,11 +32,11 @@ executables:
|
|
32
32
|
extensions: []
|
33
33
|
extra_rdoc_files: []
|
34
34
|
files:
|
35
|
-
-
|
36
|
-
-
|
37
|
-
-
|
38
|
-
-
|
39
|
-
-
|
35
|
+
- .codeclimate.yml
|
36
|
+
- .gitignore
|
37
|
+
- .gitmodules
|
38
|
+
- .rubocop.yml
|
39
|
+
- .travis.yml
|
40
40
|
- Appraisals
|
41
41
|
- CHANGELOG.md
|
42
42
|
- Gemfile
|
@@ -68,6 +68,7 @@ files:
|
|
68
68
|
- lib/rollbar/delay/delayed_job.rb
|
69
69
|
- lib/rollbar/delay/girl_friday.rb
|
70
70
|
- lib/rollbar/delay/resque.rb
|
71
|
+
- lib/rollbar/delay/shoryuken.rb
|
71
72
|
- lib/rollbar/delay/sidekiq.rb
|
72
73
|
- lib/rollbar/delay/sucker_punch.rb
|
73
74
|
- lib/rollbar/delay/thread.rb
|
@@ -270,17 +271,17 @@ require_paths:
|
|
270
271
|
- lib
|
271
272
|
required_ruby_version: !ruby/object:Gem::Requirement
|
272
273
|
requirements:
|
273
|
-
- -
|
274
|
+
- - '>='
|
274
275
|
- !ruby/object:Gem::Version
|
275
276
|
version: '0'
|
276
277
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
277
278
|
requirements:
|
278
|
-
- -
|
279
|
+
- - '>='
|
279
280
|
- !ruby/object:Gem::Version
|
280
281
|
version: '0'
|
281
282
|
requirements: []
|
282
283
|
rubyforge_project:
|
283
|
-
rubygems_version: 2.
|
284
|
+
rubygems_version: 2.6.10
|
284
285
|
signing_key:
|
285
286
|
specification_version: 4
|
286
287
|
summary: Reports exceptions to Rollbar
|