robustly 0.0.4 → 0.1.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
  SHA1:
3
- metadata.gz: 3358a29e863fa2ee454fe1d98b28cce45552d8be
4
- data.tar.gz: 36d2b9074c3539947d8b84471a5e02207db631a9
3
+ metadata.gz: 9dbd670fd6832a14e2315b0195a6bb13381eaed8
4
+ data.tar.gz: 31b9a08a7b218feedafe11b15b4a000204e0c7b3
5
5
  SHA512:
6
- metadata.gz: 1533250d894eb14a9cf777554b0c6f02db0df96d472eda9c4898fd7e95f848312c53de1367b4ec906ee62d2024139bde2e6ce1f9962454b2b5bfc87b1a0136a3
7
- data.tar.gz: 350ad47a7bf3e6b4f643e7cc8e910dde3fed37c0852acfe9b1967dcfba39fe690b075fa35aabf7c898b5a041773e39adf9cd66704a9301b64f3a3793d205cd6b
6
+ metadata.gz: 867d1290360d87b7835e8ed65159e29077ed26a896cc937284288a598e9871c048f031d1bad0bf02b399a16edbd77672bdeb0a4b56b37ff213d5ee7ee6d5a2e1
7
+ data.tar.gz: 161bc8ac868488b646f88268710d4476569b39992040c345f47e2cc17ac1122a2174e251a58fb4ac063303927a5c6a75ebcda5c4820944c36bc893c99d1eab3c
@@ -0,0 +1,5 @@
1
+ ## 0.1.0
2
+
3
+ - Added `tag` option and tag exception message by default
4
+ - Added `except` option
5
+ - Added `silence` option
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Robustly
2
2
 
3
- Don’t let small errors bring down the system
3
+ Unexpected data can cause errors in production - don’t let it bring down the system
4
4
 
5
5
  ```ruby
6
6
  safely do
@@ -8,41 +8,55 @@ safely do
8
8
  end
9
9
  ```
10
10
 
11
- Raises exceptions in development and test environments and rescues and reports exceptions elsewhere.
11
+ Exceptions are rescued and reported to your favorite reporting service.
12
12
 
13
- Also aliased as `yolo`.
13
+ In development and test environments, exceptions are raised so you can fix them. :smirk:
14
+
15
+ ## Examples
16
+
17
+ Great for analytics
14
18
 
15
19
  ```ruby
16
- yolo do
17
- # get crazy in here
18
- end
20
+ safely { track_event("Search") }
19
21
  ```
20
22
 
21
- Reports exceptions to [Rollbar](https://rollbar.com/), [Airbrake](https://airbrake.io/), [Exceptional](http://www.exceptional.io/), [Honeybadger](https://www.honeybadger.io/), [Sentry](https://getsentry.com/), [Raygun](https://raygun.io/), and [Bugsnag](https://bugsnag.com/) out of the box thanks to [Errbase](https://github.com/ankane/errbase).
22
-
23
- Customize reporting with:
23
+ and background jobs
24
24
 
25
25
  ```ruby
26
- Robustly.report_exception_method = proc {|e| Rollbar.report_exception(e) }
26
+ User.find_each do |user|
27
+ safely { cache_recommendations(user) }
28
+ end
27
29
  ```
28
30
 
29
- And throttle reporting with:
31
+ Also aliased as `yolo`.
32
+
33
+ ## Features
34
+
35
+ Throttle reporting with:
30
36
 
31
37
  ```ruby
32
- safely throttle: 1000 do
38
+ safely sample: 1000 do
33
39
  # reports ~ 1/1000 errors
34
40
  end
35
41
  ```
36
42
 
37
- Specify a default value to return on errors:
43
+ Specify a default value to return on exceptions
44
+
45
+ ```ruby
46
+ score = safely(default: 30) { calculate_score }
47
+ ```
48
+
49
+ Raise specific exceptions
38
50
 
39
51
  ```ruby
40
- safely default: 30 do
41
- # big bucks, no whammy
52
+ safely except: ActiveRecord::RecordNotUnique do
53
+ # all other exceptions will be rescued
42
54
  end
43
55
  ```
44
56
 
45
- Catch specific errors
57
+ Pass an array for multiple exception classes.
58
+
59
+ Rescue only specific exceptions
46
60
 
47
61
  ```ruby
48
62
  safely only: ActiveRecord::RecordNotUnique do
@@ -50,6 +64,38 @@ safely only: ActiveRecord::RecordNotUnique do
50
64
  end
51
65
  ```
52
66
 
67
+ Silence exceptions
68
+
69
+ ```ruby
70
+ safely(silence: ActiveRecord::RecordNotUnique) { code }
71
+ ```
72
+
73
+ ## Reporting
74
+
75
+ Reports exceptions to a variety of services out of the box thanks to [Errbase](https://github.com/ankane/errbase).
76
+
77
+ - [Rollbar](https://rollbar.com/)
78
+ - [Airbrake](https://airbrake.io/)
79
+ - [Exceptional](http://www.exceptional.io/)
80
+ - [Honeybadger](https://www.honeybadger.io/)
81
+ - [Sentry](https://getsentry.com/)
82
+ - [Raygun](https://raygun.io/)
83
+ - [Bugsnag](https://bugsnag.com/)
84
+ - [Appsignal](https://appsignal.com/)
85
+ - [Opbeat](https://opbeat.com/)
86
+
87
+ Customize reporting with:
88
+
89
+ ```ruby
90
+ Robustly.report_exception_method = proc { |e| Rollbar.error(e) }
91
+ ```
92
+
93
+ By default, exception messages are prefixed with `[safely]`. This makes it easier to spot rescued exceptions. Turn this off with:
94
+
95
+ ```ruby
96
+ Robustly.tag = false
97
+ ```
98
+
53
99
  ## Installation
54
100
 
55
101
  Add this line to your application’s Gemfile:
@@ -58,6 +104,10 @@ Add this line to your application’s Gemfile:
58
104
  gem 'robustly'
59
105
  ```
60
106
 
107
+ ## History
108
+
109
+ View the [changelog](https://github.com/ankane/robustly/blob/master/CHANGELOG.md)
110
+
61
111
  ## Contributing
62
112
 
63
113
  Everyone is encouraged to help improve this project. Here are a few ways you can help:
@@ -3,33 +3,39 @@ require "errbase"
3
3
 
4
4
  module Robustly
5
5
  class << self
6
- attr_accessor :env, :report_exception_method
6
+ attr_accessor :env, :raise_envs, :tag, :report_exception_method
7
7
 
8
8
  def report_exception(e)
9
9
  report_exception_method.call(e)
10
10
  end
11
11
  end
12
- self.env = ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development"
13
- self.report_exception_method = proc do |e|
12
+
13
+ DEFAULT_EXCEPTION_METHOD = proc do |e|
14
+ e = e.dup # leave original exception unmodified
15
+ e.message.prepend("[safely] ") if e.message && Robustly.tag
14
16
  Errbase.report(e)
15
17
  end
16
18
 
19
+ self.env = ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development"
20
+ self.tag = true
21
+ self.report_exception_method = DEFAULT_EXCEPTION_METHOD
22
+ self.raise_envs = %w(development test)
23
+
17
24
  module Methods
18
25
  def safely(options = {})
19
- class_names = Array(options[:only] || StandardError)
20
- begin
21
- yield
22
- rescue *class_names => e
23
- raise e if %w(development test).include?(Robustly.env)
24
- if options[:throttle] ? rand < 1.0 / options[:throttle] : true
25
- begin
26
- Robustly.report_exception(e)
27
- rescue => e2
28
- $stderr.puts "FAIL-SAFE #{e2.class.name}: #{e2.message}"
29
- end
26
+ yield
27
+ rescue *Array(options[:only] || StandardError) => e
28
+ raise e if Array(options[:except]).any? { |c| e.is_a?(c) }
29
+ raise e if Robustly.raise_envs.include?(Robustly.env)
30
+ sample = options[:sample] || options[:throttle]
31
+ if sample ? rand < 1.0 / sample : true
32
+ begin
33
+ Robustly.report_exception(e) unless Array(options[:silence]).any? { |c| e.is_a?(c) }
34
+ rescue => e2
35
+ $stderr.puts "FAIL-SAFE #{e2.class.name}: #{e2.message}"
30
36
  end
31
- options[:default]
32
37
  end
38
+ options[:default]
33
39
  end
34
40
  alias_method :yolo, :safely
35
41
  alias_method :robustly, :safely # legacy
@@ -1,3 +1,3 @@
1
1
  module Robustly
2
- VERSION = "0.0.4"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -3,7 +3,7 @@ require_relative "test_helper"
3
3
  class TestRobustly < Minitest::Test
4
4
  def setup
5
5
  Robustly.env = "production"
6
- Robustly.report_exception_method = proc { |e| Errbase.report(e) }
6
+ Robustly.report_exception_method = Robustly::DEFAULT_EXCEPTION_METHOD
7
7
  end
8
8
 
9
9
  def test_safely_development_environment
@@ -46,35 +46,33 @@ class TestRobustly < Minitest::Test
46
46
  assert mock.verify
47
47
  end
48
48
 
49
- def test_robustly
50
- exception = Robustly::TestError.new
51
- mock = MiniTest::Mock.new
52
- mock.expect :report_exception, nil, [exception]
53
- Robustly.report_exception_method = proc { |e| mock.report_exception(e) }
54
- robustly do
55
- raise exception
56
- end
57
- assert mock.verify
58
- end
59
-
60
49
  def test_return_value
61
50
  assert_equal 1, safely { 1 }
62
- assert_equal nil, safely { raise Robustly::TestError }
51
+ assert_equal nil, safely { raise Robustly::TestError, "Boom" }
63
52
  end
64
53
 
65
54
  def test_default
66
55
  assert_equal 1, safely(default: 2) { 1 }
67
- assert_equal 2, safely(default: 2) { raise Robustly::TestError }
56
+ assert_equal 2, safely(default: 2) { raise Robustly::TestError, "Boom" }
68
57
  end
69
58
 
70
59
  def test_only
71
60
  assert_equal nil, safely(only: Robustly::TestError) { raise Robustly::TestError }
72
- assert_raises(RuntimeError, "Boom") { safely(only: Robustly::TestError) { raise RuntimeError.new("Boom") } }
61
+ assert_raises(RuntimeError, "Boom") { safely(only: Robustly::TestError) { raise RuntimeError, "Boom" } }
73
62
  end
74
63
 
75
64
  def test_only_array
76
65
  assert_equal nil, safely(only: [Robustly::TestError]) { raise Robustly::TestError }
77
- assert_raises(RuntimeError, "Boom") { safely(only: [Robustly::TestError]) { raise RuntimeError.new("Boom") } }
66
+ assert_raises(RuntimeError, "Boom") { safely(only: [Robustly::TestError]) { raise RuntimeError, "Boom" } }
67
+ end
68
+
69
+ def test_except
70
+ assert_raises(Robustly::TestError, "Boom") { safely(except: StandardError) { raise Robustly::TestError, "Boom" } }
71
+ end
72
+
73
+ def test_silence
74
+ safely(silence: StandardError) { raise Robustly::TestError, "Boom" }
75
+ assert true
78
76
  end
79
77
 
80
78
  def test_failsafe
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: robustly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.1.0
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-11 00:00:00.000000000 Z
11
+ date: 2015-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: errbase
@@ -74,7 +74,7 @@ extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
76
  - ".gitignore"
77
- - ".rubocop.yml"
77
+ - CHANGELOG.md
78
78
  - Gemfile
79
79
  - LICENSE.txt
80
80
  - README.md
@@ -1,32 +0,0 @@
1
- Style/StringLiterals:
2
- EnforcedStyle: double_quotes
3
-
4
- Style/SpaceInsideHashLiteralBraces:
5
- EnforcedStyle: no_space
6
-
7
- Style/Documentation:
8
- Enabled: false
9
-
10
- Style/SignalException:
11
- Enabled: false
12
-
13
- Metrics/AbcSize:
14
- Enabled: false
15
-
16
- Metrics/BlockNesting:
17
- Enabled: false
18
-
19
- Metrics/ClassLength:
20
- Enabled: false
21
-
22
- Metrics/CyclomaticComplexity:
23
- Enabled: false
24
-
25
- Metrics/LineLength:
26
- Enabled: false
27
-
28
- Metrics/MethodLength:
29
- Enabled: false
30
-
31
- Metrics/PerceivedComplexity:
32
- Enabled: false