isolator 0.5.0 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6416346eed42fd67e5cc8e6801f983fee64666e21547e603e0c137f9e6fffad6
4
- data.tar.gz: b8e18e6b741c1fb19726957e99f4e04b83cb70e008cf1100db9c4fab5737250f
3
+ metadata.gz: d5c027f6c2e795b8aeb009340efd8a920556cfb47553a06d93f4feab8d7c79de
4
+ data.tar.gz: 3ae481ffdf7eba4d080402d44c7355c558363b0228053091ca96edc55bd26847
5
5
  SHA512:
6
- metadata.gz: 821a71fc3afe8425b7eb7aef194c43213de681b7b2f9b468968a6dcb8479a114797451894e49ff9ea4da40f1594957e555a9c752ade26b7b76c8a80cc3eba653
7
- data.tar.gz: 6440b717a3caa57454f1a6c6a5803717641e9dc32e7ef397572f131acf37f716d9f3f573ce3796c0b064fac2f0edcbdfd60ea3dec8e4b8712eca225782a9ba4d
6
+ metadata.gz: '008f26a3b4e3d059332e25a0b193dcec4586a17b6d6df9259b8b13e94a85e214e2c16aa37197a5490e92ba3cc288ce656c3ae1e1061e7ae7968ff4b967d327f1'
7
+ data.tar.gz: 2a4237282734486458d04f45474eee2a75367724808f8079801645ffe978981725f6d46e6db1de041d8c36d2cd1a5832b7f09f44e2773c609013560bd9ee5904
@@ -41,6 +41,9 @@ Style/StringLiterals:
41
41
  Style/RegexpLiteral:
42
42
  Enabled: false
43
43
 
44
+ Style/Lambda:
45
+ Enabled: false
46
+
44
47
  Style/BlockDelimiters:
45
48
  Exclude:
46
49
  - 'spec/**/*.rb'
@@ -56,6 +59,8 @@ Lint/AmbiguousRegexpLiteral:
56
59
 
57
60
  Metrics/LineLength:
58
61
  Max: 100
62
+ Exclude:
63
+ - 'spec/**/*.rb'
59
64
 
60
65
  Metrics/BlockLength:
61
66
  Exclude:
@@ -1,11 +1,16 @@
1
1
  sudo: false
2
2
  language: ruby
3
+ cache: bundler
3
4
  rvm:
4
- - 2.5.0
5
+ - 2.5.3
5
6
 
6
7
  notifications:
7
8
  email: false
8
9
 
10
+ before_install:
11
+ - (ruby -v | grep '2.2.2') || gem update --system
12
+ - gem install bundler -v '< 2'
13
+
9
14
  matrix:
10
15
  fast_finish: true
11
16
  include:
@@ -13,6 +18,8 @@ matrix:
13
18
  gemfile: gemfiles/railsmaster.gemfile
14
19
  - rvm: jruby-9.1.0.0
15
20
  gemfile: gemfiles/jruby.gemfile
21
+ - rvm: 2.6.1
22
+ gemfile: gemfiles/rails6.gemfile
16
23
  - rvm: 2.5.0
17
24
  gemfile: Gemfile
18
25
  - rvm: 2.4.3
@@ -2,6 +2,18 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.6.0 (2019-04-12) 🚀
6
+
7
+ - Add support for exceptions message details. ([@palkan][])
8
+
9
+ Make it possible to provide more information about the cause of the failure
10
+ (for example, job class and arguments for background jobs, URL for HTTP).
11
+
12
+ - Change backtrace filtering behaviour. ([@palkan][])
13
+
14
+ The default behaviour is to take the top five lines.
15
+ You can customize it via `Isolator.config.backtrace_filter`.
16
+
5
17
  ## 0.5.0 (2018-08-29)
6
18
 
7
19
  - [PR [#19](https://github.com/palkan/isolator/pull/19)] Adding support for ruby version 2.2.2. ([@shivanshgaur][])
data/Gemfile CHANGED
@@ -7,7 +7,7 @@ gemspec
7
7
 
8
8
  gem "pry-byebug"
9
9
 
10
- gem "sqlite3"
10
+ gem "sqlite3", "~> 1.3.0"
11
11
 
12
12
  local_gemfile = File.join(__dir__, "Gemfile.local")
13
13
 
data/README.md CHANGED
@@ -91,6 +91,10 @@ Isolator.configure do |config|
91
91
 
92
92
  # Send notifications to uniform_notifier
93
93
  config.send_notifications = false
94
+
95
+ # Customize backtrace filtering (provide a callable)
96
+ # By default, just takes the top-5 lines
97
+ config.backtrace_filter = ->(backtrace) { backtrace.take(5) }
94
98
  end
95
99
  ```
96
100
 
@@ -186,6 +190,17 @@ Isolator.isolate :danger, Danger.singleton_class, :explode, options
186
190
  Possible `options` are:
187
191
  - `exception_class` – an exception class to raise in case of offense
188
192
  - `exception_message` – custom exception message (could be specified without a class)
193
+ - `details_message` – a block to generate additional exceptin message information:
194
+
195
+ ```ruby
196
+ Isolator.isolate :active_job,
197
+ target: ActiveJob::Base,
198
+ method_name: :enqueue,
199
+ exception_class: Isolator::BackgroundJobError,
200
+ details_message: ->(obj, _args) {
201
+ "#{obj.class.name}(#{obj.arguments})"
202
+ }
203
+ ```
189
204
 
190
205
  You can also add some callbacks to be run before and after the transaction:
191
206
 
@@ -1,7 +1,7 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gem "rails", "~> 4.2"
4
- gem "sqlite3"
4
+ gem "sqlite3", "~> 1.3.0"
5
5
  gem 'uniform_notifier', '~> 1.11'
6
6
 
7
7
  gemspec path: ".."
@@ -0,0 +1,7 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "rails", "6.0.0.beta3"
4
+ gem "sqlite3", "~> 1.3"
5
+ gem 'uniform_notifier', '~> 1.11'
6
+
7
+ gemspec path: ".."
@@ -1,6 +1,5 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "arel", github: "rails/arel"
4
3
  gem "rails", github: "rails/rails"
5
4
  gem "sqlite3"
6
5
  gem 'uniform_notifier', '~> 1.11'
@@ -1,7 +1,7 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gem "rails", "~> 4.2"
4
- gem "sqlite3"
4
+ gem "sqlite3", "~> 1.3.0"
5
5
  gem 'uniform_notifier', '1.11'
6
6
  gem 'anyway_config', '1.2'
7
7
 
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.add_runtime_dependency "sniffer", "~> 0.3.1"
24
24
 
25
- spec.add_development_dependency "bundler", "~> 1.14"
25
+ spec.add_development_dependency "bundler", ">= 1.16"
26
26
  spec.add_development_dependency "rake", "~> 10.0"
27
27
  spec.add_development_dependency "rspec", "~> 3.0"
28
28
  spec.add_development_dependency "rspec-rails", "~> 3.0"
@@ -11,6 +11,7 @@ module Isolator
11
11
 
12
12
  self.exception_class = options[:exception_class] if options.key?(:exception_class)
13
13
  self.exception_message = options[:exception_message] if options.key?(:exception_message)
14
+ self.details_message = options[:details_message] if options.key?(:details_message)
14
15
  end
15
16
 
16
17
  add_patch_method(adapter, target, method_name) if
@@ -21,7 +22,7 @@ module Isolator
21
22
  def self.add_patch_method(adapter, base, method_name)
22
23
  mod = Module.new do
23
24
  define_method method_name do |*args, &block|
24
- adapter.notify(caller, *args)
25
+ adapter.notify(caller, self, *args)
25
26
  super(*args, &block)
26
27
  end
27
28
  end
@@ -3,4 +3,8 @@
3
3
  Isolator.isolate :active_job,
4
4
  target: ActiveJob::Base,
5
5
  method_name: :enqueue,
6
- exception_class: Isolator::BackgroundJobError
6
+ exception_class: Isolator::BackgroundJobError,
7
+ details_message: ->(obj, _args) {
8
+ "#{obj.class.name}" \
9
+ "#{obj.arguments.any? ? " (#{obj.arguments.join(', ')})" : ''}"
10
+ }
@@ -3,4 +3,7 @@
3
3
  Isolator.isolate :resque,
4
4
  target: Resque.singleton_class,
5
5
  method_name: :enqueue,
6
- exception_class: Isolator::BackgroundJobError
6
+ exception_class: Isolator::BackgroundJobError,
7
+ details_message: ->(_obj, args) {
8
+ args.join(", ")
9
+ }
@@ -3,4 +3,7 @@
3
3
  Isolator.isolate :resque_scheduler,
4
4
  target: Resque.singleton_class,
5
5
  method_name: :enqueue_at,
6
- exception_class: Isolator::BackgroundJobError
6
+ exception_class: Isolator::BackgroundJobError,
7
+ details_message: ->(_obj, (ts, *args)) {
8
+ "#{args.join(', ')} (at #{ts})"
9
+ }
@@ -3,4 +3,9 @@
3
3
  Isolator.isolate :sidekiq,
4
4
  target: Sidekiq::Client,
5
5
  method_name: :raw_push,
6
- exception_class: Isolator::BackgroundJobError
6
+ exception_class: Isolator::BackgroundJobError,
7
+ details_message: ->(_obj, args) {
8
+ args.first.map do |job|
9
+ "#{job['class']} (#{job['args']})"
10
+ end.join("\n")
11
+ }
@@ -3,4 +3,7 @@
3
3
  Isolator.isolate :sucker_punch,
4
4
  target: SuckerPunch::Queue.singleton_class,
5
5
  method_name: :find_or_create,
6
- exception_class: Isolator::BackgroundJobError
6
+ exception_class: Isolator::BackgroundJobError,
7
+ details_message: ->(_obj, args) {
8
+ args.compact.join(", ")
9
+ }
@@ -4,7 +4,7 @@ module Isolator
4
4
  module Adapters
5
5
  # Used as a "template" for adapters
6
6
  module Base
7
- attr_accessor :exception_class, :exception_message
7
+ attr_accessor :exception_class, :exception_message, :details_message
8
8
 
9
9
  def disable!
10
10
  @disabled = true
@@ -22,9 +22,9 @@ module Isolator
22
22
  @disabled == true
23
23
  end
24
24
 
25
- def notify(backtrace, *args)
25
+ def notify(backtrace, obj, *args)
26
26
  return unless notify?(*args)
27
- Isolator.notify(exception: build_exception, backtrace: backtrace)
27
+ Isolator.notify(exception: build_exception(obj, args), backtrace: backtrace)
28
28
  end
29
29
 
30
30
  def notify?(*args)
@@ -45,9 +45,10 @@ module Isolator
45
45
 
46
46
  private
47
47
 
48
- def build_exception
48
+ def build_exception(obj, args)
49
49
  klass = exception_class || Isolator::UnsafeOperationError
50
- klass.new(exception_message)
50
+ details = details_message.call(obj, args) if details_message
51
+ klass.new(exception_message, details: details)
51
52
  end
52
53
  end
53
54
  end
@@ -7,7 +7,11 @@ Sniffer::Config.defaults["logger"] = nil
7
7
 
8
8
  Isolator.isolate :http, target: Sniffer.singleton_class,
9
9
  method_name: :store,
10
- exception_class: Isolator::HTTPError
10
+ exception_class: Isolator::HTTPError,
11
+ details_message: ->(_obj, args) {
12
+ req = args.first.request
13
+ "#{req[:method]} #{req[:host]}/#{req[:query]}"
14
+ }
11
15
 
12
16
  Isolator.before_isolate do
13
17
  next if Isolator.adapters.http.disabled?
@@ -1,6 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- adapter = Isolator.isolate :webmock, exception_class: Isolator::HTTPError
3
+ adapter = Isolator.isolate :webmock,
4
+ exception_class: Isolator::HTTPError,
5
+ details_message: ->(obj, _args) {
6
+ "#{obj.method.to_s.upcase} #{obj.uri}"
7
+ }
4
8
 
5
9
  WebMock.after_request do |*args|
6
10
  adapter.notify(caller, *args)
@@ -1,4 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- Isolator.isolate :mailer, target: Mail::Message, method_name: :deliver,
4
- exception_class: Isolator::MailerError
3
+ Isolator.isolate :mailer, target: Mail::Message,
4
+ method_name: :deliver,
5
+ exception_class: Isolator::MailerError,
6
+ details_message: ->(obj, _args) {
7
+ "From: #{obj.from}\n" \
8
+ "To: #{obj.to}\n" \
9
+ "Subject: #{obj.subject}"
10
+ }
@@ -12,12 +12,14 @@ module Isolator
12
12
  # - `send_notifications` - whether to send notifications (through uniform_notifier);
13
13
  # defauls to false
14
14
  class Configuration
15
- attr_accessor :raise_exceptions, :logger, :send_notifications
15
+ attr_accessor :raise_exceptions, :logger, :send_notifications,
16
+ :backtrace_filter
16
17
 
17
18
  def initialize
18
19
  @logger = nil
19
20
  @raise_exceptions = test_env?
20
21
  @send_notifications = false
22
+ @backtrace_filter = ->(backtrace) { backtrace.take(5) }
21
23
  end
22
24
 
23
25
  alias raise_exceptions? raise_exceptions
@@ -4,9 +4,9 @@ module Isolator # :nodoc: all
4
4
  class UnsafeOperationError < StandardError
5
5
  MESSAGE = "You are trying to do unsafe operation inside db transaction"
6
6
 
7
- def initialize(msg = nil)
7
+ def initialize(msg = nil, details: nil)
8
8
  msg ||= self.class::MESSAGE
9
- super
9
+ super(details ? "#{msg}\nDetails: #{details}" : msg)
10
10
  end
11
11
  end
12
12
 
@@ -48,7 +48,7 @@ module Isolator
48
48
  end
49
49
 
50
50
  def filtered_backtrace
51
- backtrace.reject { |line| line =~ /\/(gems|ruby)/ }.take_while { |line| line !~ /ruby/ }
51
+ Isolator.config.backtrace_filter.call(backtrace)
52
52
  end
53
53
 
54
54
  def uniform_notifier_loaded?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Isolator
4
- VERSION = "0.5.0"
4
+ VERSION = "0.6.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isolator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-02 00:00:00.000000000 Z
11
+ date: 2019-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sniffer
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '1.14'
33
+ version: '1.16'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '1.14'
40
+ version: '1.16'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -253,6 +253,7 @@ files:
253
253
  - bin/setup
254
254
  - gemfiles/activerecord42.gemfile
255
255
  - gemfiles/jruby.gemfile
256
+ - gemfiles/rails6.gemfile
256
257
  - gemfiles/railsmaster.gemfile
257
258
  - gemfiles/ruby_2.2.2.gemfile
258
259
  - isolator.gemspec
@@ -306,8 +307,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
306
307
  - !ruby/object:Gem::Version
307
308
  version: '0'
308
309
  requirements: []
309
- rubyforge_project:
310
- rubygems_version: 2.7.6
310
+ rubygems_version: 3.0.2
311
311
  signing_key:
312
312
  specification_version: 4
313
313
  summary: Detect non-atomic interactions within DB transactions