rollbar 2.15.0 → 2.15.1
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 +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 [](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
|