safely_block 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 65bad436ec7ddcd49ef1836e3ec0f077b8754290
4
+ data.tar.gz: fcafabce7a11b00143410a3083f78cbdee24bab3
5
+ SHA512:
6
+ metadata.gz: 180b1e137dcf01415624ea95333f2e571cd96edcaedb628ed99d83cb32d787ba470f8afc8f4084352cce7f5b162719bee5435e8742a431391dd0b5c95a0a4ff3
7
+ data.tar.gz: 381c7aa036d20fd55577d67425e2f4a264af515231bb65c25d124b8bf68c0eb3f789cfe4338f4c859d8ce69d8ccaaf931e7317c20287982c4068655992bb72bd
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/CHANGELOG.md ADDED
@@ -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/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in safely_block.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Andrew Kane
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,118 @@
1
+ # Safely
2
+
3
+ Unexpected data can cause errors in production - don’t let it bring down the system
4
+
5
+ ```ruby
6
+ safely do
7
+ # keep going if this code fails
8
+ end
9
+ ```
10
+
11
+ Exceptions are rescued and reported to your favorite reporting service.
12
+
13
+ In development and test environments, exceptions are raised so you can fix them. :smirk:
14
+
15
+ ## Examples
16
+
17
+ Great for analytics
18
+
19
+ ```ruby
20
+ safely { track_event("Search") }
21
+ ```
22
+
23
+ and background jobs
24
+
25
+ ```ruby
26
+ User.find_each do |user|
27
+ safely { cache_recommendations(user) }
28
+ end
29
+ ```
30
+
31
+ Also aliased as `yolo`.
32
+
33
+ ## Features
34
+
35
+ Throttle reporting with:
36
+
37
+ ```ruby
38
+ safely sample: 1000 do
39
+ # reports ~ 1/1000 errors
40
+ end
41
+ ```
42
+
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
50
+
51
+ ```ruby
52
+ safely except: ActiveRecord::RecordNotUnique do
53
+ # all other exceptions will be rescued
54
+ end
55
+ ```
56
+
57
+ Pass an array for multiple exception classes.
58
+
59
+ Rescue only specific exceptions
60
+
61
+ ```ruby
62
+ safely only: ActiveRecord::RecordNotUnique do
63
+ # all other exceptions will be raised
64
+ end
65
+ ```
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
+ Safely.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
+ Safely.tag = false
97
+ ```
98
+
99
+ ## Installation
100
+
101
+ Add this line to your application’s Gemfile:
102
+
103
+ ```ruby
104
+ gem 'safely_block'
105
+ ```
106
+
107
+ ## History
108
+
109
+ View the [changelog](https://github.com/ankane/safely/blob/master/CHANGELOG.md)
110
+
111
+ ## Contributing
112
+
113
+ Everyone is encouraged to help improve this project. Here are a few ways you can help:
114
+
115
+ - [Report bugs](https://github.com/ankane/safely/issues)
116
+ - Fix bugs and [submit pull requests](https://github.com/ankane/safely/pulls)
117
+ - Write, clarify, or fix documentation
118
+ - Suggest or add new features
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ task default: :test
5
+ Rake::TestTask.new do |t|
6
+ t.libs << "test"
7
+ t.pattern = "test/**/*_test.rb"
8
+ end
@@ -0,0 +1,45 @@
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
44
+
45
+ Object.send :include, Safely::Methods
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "safely_block"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "safely_block"
8
+ spec.version = Safely::VERSION
9
+ spec.authors = ["Andrew Kane"]
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"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "errbase"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.6"
24
+ spec.add_development_dependency "rake"
25
+ spec.add_development_dependency "minitest", ">= 5"
26
+ end
@@ -0,0 +1,85 @@
1
+ require_relative "test_helper"
2
+
3
+ class TestSafely < Minitest::Test
4
+ def setup
5
+ Safely.env = "production"
6
+ Safely.report_exception_method = Safely::DEFAULT_EXCEPTION_METHOD
7
+ end
8
+
9
+ def test_development_environment
10
+ Safely.env = "development"
11
+ assert_raises(Safely::TestError) do
12
+ safely do
13
+ raise Safely::TestError
14
+ end
15
+ end
16
+ end
17
+
18
+ def test_test_environment
19
+ Safely.env = "test"
20
+ assert_raises(Safely::TestError) do
21
+ safely do
22
+ raise Safely::TestError
23
+ end
24
+ end
25
+ end
26
+
27
+ def test_production_environment
28
+ exception = Safely::TestError.new
29
+ mock = MiniTest::Mock.new
30
+ mock.expect :report_exception, nil, [exception]
31
+ Safely.report_exception_method = proc { |e| mock.report_exception(e) }
32
+ safely do
33
+ raise exception
34
+ end
35
+ assert mock.verify
36
+ end
37
+
38
+ def test_yolo
39
+ exception = Safely::TestError.new
40
+ mock = MiniTest::Mock.new
41
+ mock.expect :report_exception, nil, [exception]
42
+ Safely.report_exception_method = proc { |e| mock.report_exception(e) }
43
+ yolo do
44
+ raise exception
45
+ end
46
+ assert mock.verify
47
+ end
48
+
49
+ def test_return_value
50
+ assert_equal 1, safely { 1 }
51
+ assert_equal nil, safely { raise Safely::TestError, "Boom" }
52
+ end
53
+
54
+ def test_default
55
+ assert_equal 1, safely(default: 2) { 1 }
56
+ assert_equal 2, safely(default: 2) { raise Safely::TestError, "Boom" }
57
+ end
58
+
59
+ def test_only
60
+ assert_equal nil, safely(only: Safely::TestError) { raise Safely::TestError }
61
+ assert_raises(RuntimeError, "Boom") { safely(only: Safely::TestError) { raise "Boom" } }
62
+ end
63
+
64
+ def test_only_array
65
+ assert_equal nil, safely(only: [Safely::TestError]) { raise Safely::TestError }
66
+ assert_raises(RuntimeError, "Boom") { safely(only: [Safely::TestError]) { raise "Boom" } }
67
+ end
68
+
69
+ def test_except
70
+ assert_raises(Safely::TestError, "Boom") { safely(except: StandardError) { raise Safely::TestError, "Boom" } }
71
+ end
72
+
73
+ def test_silence
74
+ safely(silence: StandardError) { raise Safely::TestError, "Boom" }
75
+ assert true
76
+ end
77
+
78
+ def test_failsafe
79
+ Safely.report_exception_method = proc { raise "oops" }
80
+ out, err = capture_io do
81
+ safely { raise "boom" }
82
+ end
83
+ assert_equal "FAIL-SAFE RuntimeError: oops\n", err
84
+ end
85
+ end
@@ -0,0 +1,8 @@
1
+ require "bundler/setup"
2
+ Bundler.require(:default)
3
+ require "minitest/autorun"
4
+ require "minitest/pride"
5
+
6
+ module Safely
7
+ class TestError < StandardError; end
8
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: safely_block
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Kane
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: errbase
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.6'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '5'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '5'
69
+ description: Don’t let small errors bring down the system
70
+ email:
71
+ - andrew@chartkick.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - CHANGELOG.md
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - lib/safely_block.rb
83
+ - safely_block.gemspec
84
+ - test/safely_test.rb
85
+ - test/test_helper.rb
86
+ homepage: https://github.com/ankane/safely_block
87
+ licenses:
88
+ - MIT
89
+ metadata: {}
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.4.5
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: Don’t let small errors bring down the system
110
+ test_files:
111
+ - test/safely_test.rb
112
+ - test/test_helper.rb
113
+ has_rdoc: