safely_block 0.1.0 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 65bad436ec7ddcd49ef1836e3ec0f077b8754290
4
- data.tar.gz: fcafabce7a11b00143410a3083f78cbdee24bab3
3
+ metadata.gz: 9ba20f765b3e7d5a3a42de0c5376d06f2fa1a123
4
+ data.tar.gz: 100cf5b7ab1a8fba676b64e7914908d7d23f8276
5
5
  SHA512:
6
- metadata.gz: 180b1e137dcf01415624ea95333f2e571cd96edcaedb628ed99d83cb32d787ba470f8afc8f4084352cce7f5b162719bee5435e8742a431391dd0b5c95a0a4ff3
7
- data.tar.gz: 381c7aa036d20fd55577d67425e2f4a264af515231bb65c25d124b8bf68c0eb3f789cfe4338f4c859d8ce69d8ccaaf931e7317c20287982c4068655992bb72bd
6
+ metadata.gz: c781fdff6e44069440281ba046b853e97a187c0ef59110231c4571113abd6451f15ecbb94484b7c53afcd0c2d07e24f8ddd28a3cd1ed843611dfcb2d97b73ee2
7
+ data.tar.gz: 1d261002fdf45d8fe088a75203ce55e61467aefb41547abbbad2ae617384f3f9bb3579b3ea961e24369daa21666dcd91803fde2eb8c9accd9a41521f1625d765
@@ -1,3 +1,8 @@
1
+ ## 0.1.1
2
+
3
+ - Added `Safely.safely` to not pollute when included in gems
4
+ - Added `throttle` option
5
+
1
6
  ## 0.1.0
2
7
 
3
8
  - Added `tag` option and tag exception message by default
data/README.md CHANGED
@@ -1,30 +1,28 @@
1
1
  # Safely
2
2
 
3
- Unexpected data can cause errors in production - don’t let it bring down the system
4
-
5
3
  ```ruby
6
4
  safely do
7
5
  # keep going if this code fails
8
6
  end
9
7
  ```
10
8
 
11
- Exceptions are rescued and reported to your favorite reporting service.
9
+ Exceptions are rescued and automatically reported to your favorite reporting service.
12
10
 
13
- In development and test environments, exceptions are raised so you can fix them. :smirk:
11
+ In development and test environments, exceptions are raised so you can fix them.
14
12
 
15
- ## Examples
13
+ ## Use It Everywhere
16
14
 
17
- Great for analytics
15
+ “Oh no, analytics brought down search”
18
16
 
19
17
  ```ruby
20
- safely { track_event("Search") }
18
+ safely { track_search(params) }
21
19
  ```
22
20
 
23
- and background jobs
21
+ “Recommendations stopped updating because of one bad user”
24
22
 
25
23
  ```ruby
26
- User.find_each do |user|
27
- safely { cache_recommendations(user) }
24
+ users.each do |user|
25
+ safely { update_recommendations(user) }
28
26
  end
29
27
  ```
30
28
 
@@ -32,18 +30,10 @@ Also aliased as `yolo`.
32
30
 
33
31
  ## Features
34
32
 
35
- Throttle reporting with:
36
-
37
- ```ruby
38
- safely sample: 1000 do
39
- # reports ~ 1/1000 errors
40
- end
41
- ```
42
-
43
33
  Specify a default value to return on exceptions
44
34
 
45
35
  ```ruby
46
- score = safely(default: 30) { calculate_score }
36
+ show_banner = safely(default: true) { show_banner_logic }
47
37
  ```
48
38
 
49
39
  Raise specific exceptions
@@ -70,6 +60,16 @@ Silence exceptions
70
60
  safely(silence: ActiveRecord::RecordNotUnique) { code }
71
61
  ```
72
62
 
63
+ Throttle reporting with:
64
+
65
+ ```ruby
66
+ safely throttle: {limit: 10, period: 1.minute} do
67
+ # reports only first 10 exceptions each minute
68
+ end
69
+ ```
70
+
71
+ **Note:** The throttle limit is approximate and per process.
72
+
73
73
  ## Reporting
74
74
 
75
75
  Reports exceptions to a variety of services out of the box thanks to [Errbase](https://github.com/ankane/errbase).
@@ -96,6 +96,12 @@ By default, exception messages are prefixed with `[safely]`. This makes it easie
96
96
  Safely.tag = false
97
97
  ```
98
98
 
99
+ To report exceptions manually:
100
+
101
+ ```ruby
102
+ Safely.report_exception(e)
103
+ ```
104
+
99
105
  ## Installation
100
106
 
101
107
  Add this line to your application’s Gemfile:
@@ -0,0 +1,57 @@
1
+ require "safely/version"
2
+ require "errbase"
3
+ require "digest"
4
+
5
+ module Safely
6
+ class << self
7
+ attr_accessor :raise_envs, :tag, :report_exception_method, :throttle_counter
8
+ attr_writer :env
9
+
10
+ def report_exception(e)
11
+ report_exception_method.call(e)
12
+ end
13
+
14
+ def env
15
+ @env ||= ENV["RAILS_ENV"] || ENV["RACK_ENV"] || "development"
16
+ end
17
+
18
+ def throttled?(e, options)
19
+ return false unless options
20
+ key = "#{options[:key] || Digest::MD5.hexdigest([e.class.name, e.message, e.backtrace.join("\n")].join("/"))}/#{(Time.now.to_i / options[:period]) * options[:period]}"
21
+ throttle_counter.clear if throttle_counter.size > 1000 # prevent from growing indefinitely
22
+ (throttle_counter[key] += 1) > options[:limit]
23
+ end
24
+ end
25
+
26
+ DEFAULT_EXCEPTION_METHOD = proc do |e|
27
+ e = e.dup # leave original exception unmodified
28
+ e.message.prepend("[safely] ") if e.message && Safely.tag
29
+ Errbase.report(e)
30
+ end
31
+
32
+ self.tag = true
33
+ self.report_exception_method = DEFAULT_EXCEPTION_METHOD
34
+ self.raise_envs = %w(development test)
35
+ # not thread-safe, but we don't need to be exact
36
+ self.throttle_counter = Hash.new(0)
37
+
38
+ module Methods
39
+ def safely(options = {})
40
+ yield
41
+ rescue *Array(options[:only] || StandardError) => e
42
+ raise e if Array(options[:except]).any? { |c| e.is_a?(c) }
43
+ raise e if Safely.raise_envs.include?(Safely.env)
44
+ sample = options[:sample]
45
+ if sample ? rand < 1.0 / sample : true
46
+ begin
47
+ Safely.report_exception(e) unless Array(options[:silence]).any? { |c| e.is_a?(c) } || Safely.throttled?(e, options[:throttle])
48
+ rescue => e2
49
+ $stderr.puts "FAIL-SAFE #{e2.class.name}: #{e2.message}"
50
+ end
51
+ end
52
+ options[:default]
53
+ end
54
+ alias_method :yolo, :safely
55
+ end
56
+ extend Methods
57
+ end
@@ -0,0 +1,3 @@
1
+ module Safely
2
+ VERSION = "0.1.1"
3
+ end
@@ -1,45 +1,3 @@
1
- require "errbase"
2
-
3
- module Safely
4
- VERSION = "0.1.0"
5
-
6
- class << self
7
- attr_accessor :env, :raise_envs, :tag, :report_exception_method
8
-
9
- def report_exception(e)
10
- report_exception_method.call(e)
11
- end
12
- end
13
-
14
- DEFAULT_EXCEPTION_METHOD = proc do |e|
15
- e = e.dup # leave original exception unmodified
16
- e.message.prepend("[safely] ") if e.message && Safely.tag
17
- Errbase.report(e)
18
- end
19
-
20
- self.env = ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development"
21
- self.tag = true
22
- self.report_exception_method = DEFAULT_EXCEPTION_METHOD
23
- self.raise_envs = %w(development test)
24
-
25
- module Methods
26
- def safely(options = {})
27
- yield
28
- rescue *Array(options[:only] || StandardError) => e
29
- raise e if Array(options[:except]).any? { |c| e.is_a?(c) }
30
- raise e if Safely.raise_envs.include?(Safely.env)
31
- sample = options[:sample]
32
- if sample ? rand < 1.0 / sample : true
33
- begin
34
- Safely.report_exception(e) unless Array(options[:silence]).any? { |c| e.is_a?(c) }
35
- rescue => e2
36
- $stderr.puts "FAIL-SAFE #{e2.class.name}: #{e2.message}"
37
- end
38
- end
39
- options[:default]
40
- end
41
- alias_method :yolo, :safely
42
- end
43
- end
1
+ require "safely/core"
44
2
 
45
3
  Object.send :include, Safely::Methods
@@ -1,16 +1,16 @@
1
1
  # coding: utf-8
2
2
  lib = File.expand_path("../lib", __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "safely_block"
4
+ require "safely/version"
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = "safely_block"
8
8
  spec.version = Safely::VERSION
9
9
  spec.authors = ["Andrew Kane"]
10
10
  spec.email = ["andrew@chartkick.com"]
11
- spec.summary = "Don’t let small errors bring down the system"
12
- spec.description = "Don’t let small errors bring down the system"
13
- spec.homepage = "https://github.com/ankane/safely_block"
11
+ spec.summary = "Awesome exception handling"
12
+ spec.description = "Awesome exception handling"
13
+ spec.homepage = "https://github.com/ankane/safely"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
@@ -82,4 +82,26 @@ class TestSafely < Minitest::Test
82
82
  end
83
83
  assert_equal "FAIL-SAFE RuntimeError: oops\n", err
84
84
  end
85
+
86
+ def test_throttle
87
+ count = 0
88
+ Safely.report_exception_method = proc { |e| count += 1 }
89
+ 5.times do |n|
90
+ safely throttle: {limit: 2, period: 3600} do
91
+ raise Safely::TestError
92
+ end
93
+ end
94
+ assert_equal 2, count
95
+ end
96
+
97
+ def test_throttle_key
98
+ count = 0
99
+ Safely.report_exception_method = proc { |e| count += 1 }
100
+ 5.times do |n|
101
+ safely throttle: {limit: 2, period: 3600, key: "boom#{n % 2}"} do
102
+ raise Safely::TestError
103
+ end
104
+ end
105
+ assert_equal 4, count
106
+ end
85
107
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: safely_block
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-15 00:00:00.000000000 Z
11
+ date: 2016-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: errbase
@@ -66,7 +66,7 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '5'
69
- description: Don’t let small errors bring down the system
69
+ description: Awesome exception handling
70
70
  email:
71
71
  - andrew@chartkick.com
72
72
  executables: []
@@ -79,11 +79,13 @@ files:
79
79
  - LICENSE.txt
80
80
  - README.md
81
81
  - Rakefile
82
+ - lib/safely/core.rb
83
+ - lib/safely/version.rb
82
84
  - lib/safely_block.rb
83
85
  - safely_block.gemspec
84
86
  - test/safely_test.rb
85
87
  - test/test_helper.rb
86
- homepage: https://github.com/ankane/safely_block
88
+ homepage: https://github.com/ankane/safely
87
89
  licenses:
88
90
  - MIT
89
91
  metadata: {}
@@ -103,10 +105,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
105
  version: '0'
104
106
  requirements: []
105
107
  rubyforge_project:
106
- rubygems_version: 2.4.5
108
+ rubygems_version: 2.6.1
107
109
  signing_key:
108
110
  specification_version: 4
109
- summary: Don’t let small errors bring down the system
111
+ summary: Awesome exception handling
110
112
  test_files:
111
113
  - test/safely_test.rb
112
114
  - test/test_helper.rb