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 +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +66 -16
- data/lib/robustly.rb +21 -15
- data/lib/robustly/version.rb +1 -1
- data/test/robustly_test.rb +14 -16
- metadata +3 -3
- data/.rubocop.yml +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9dbd670fd6832a14e2315b0195a6bb13381eaed8
|
4
|
+
data.tar.gz: 31b9a08a7b218feedafe11b15b4a000204e0c7b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 867d1290360d87b7835e8ed65159e29077ed26a896cc937284288a598e9871c048f031d1bad0bf02b399a16edbd77672bdeb0a4b56b37ff213d5ee7ee6d5a2e1
|
7
|
+
data.tar.gz: 161bc8ac868488b646f88268710d4476569b39992040c345f47e2cc17ac1122a2174e251a58fb4ac063303927a5c6a75ebcda5c4820944c36bc893c99d1eab3c
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Robustly
|
2
2
|
|
3
|
-
|
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
|
-
|
11
|
+
Exceptions are rescued and reported to your favorite reporting service.
|
12
12
|
|
13
|
-
|
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
|
-
|
17
|
-
# get crazy in here
|
18
|
-
end
|
20
|
+
safely { track_event("Search") }
|
19
21
|
```
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
Customize reporting with:
|
23
|
+
and background jobs
|
24
24
|
|
25
25
|
```ruby
|
26
|
-
|
26
|
+
User.find_each do |user|
|
27
|
+
safely { cache_recommendations(user) }
|
28
|
+
end
|
27
29
|
```
|
28
30
|
|
29
|
-
|
31
|
+
Also aliased as `yolo`.
|
32
|
+
|
33
|
+
## Features
|
34
|
+
|
35
|
+
Throttle reporting with:
|
30
36
|
|
31
37
|
```ruby
|
32
|
-
safely
|
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
|
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
|
41
|
-
#
|
52
|
+
safely except: ActiveRecord::RecordNotUnique do
|
53
|
+
# all other exceptions will be rescued
|
42
54
|
end
|
43
55
|
```
|
44
56
|
|
45
|
-
|
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:
|
data/lib/robustly.rb
CHANGED
@@ -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
|
-
|
13
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
data/lib/robustly/version.rb
CHANGED
data/test/robustly_test.rb
CHANGED
@@ -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 =
|
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
|
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
|
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
|
+
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
|
+
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
|
-
-
|
77
|
+
- CHANGELOG.md
|
78
78
|
- Gemfile
|
79
79
|
- LICENSE.txt
|
80
80
|
- README.md
|
data/.rubocop.yml
DELETED
@@ -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
|