temescal 0.1.3 → 0.1.4
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/README.md +2 -1
- data/lib/temescal/configuration.rb +10 -0
- data/lib/temescal/error.rb +1 -1
- data/lib/temescal/monitors.rb +10 -0
- data/lib/temescal/response.rb +2 -2
- data/lib/temescal/version.rb +1 -1
- data/spec/lib/temescal/configuration_spec.rb +3 -3
- data/spec/lib/temescal/error_spec.rb +21 -21
- data/spec/lib/temescal/middleware_spec.rb +33 -17
- data/spec/lib/temescal/monitors_spec.rb +30 -12
- data/spec/spec_helper.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99d0eb1cb114d96a76bdc45a6f31beb902d05028
|
4
|
+
data.tar.gz: 823a730b2904628aa8db967e31fed3d4630faad3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b43e4795769e8de711b82ba6395d885eb01c8c653f4ad433b7dbbc42c118e55d2d00ae9dd0f96acf4638b05de2660ace17984a5fd90c03265058a75a7afc4df
|
7
|
+
data.tar.gz: 5afc871cd1ffa133dacae0eb0e32ae7b8d1b8b8b581a431e02019dee9330cb7a0d531f3aa8dda12efbc6ddb43552e9b8c16e6adfd3824b348beca0850d8984da
|
data/README.md
CHANGED
@@ -43,6 +43,7 @@ The services currently supported are:
|
|
43
43
|
* [Airbrake](https://airbrake.io/)
|
44
44
|
* [Bugsnag](https://bugsnag.com/)
|
45
45
|
* [New Relic](http://newrelic.com/)
|
46
|
+
* [Honeybadger](https://www.honeybadger.io/)
|
46
47
|
|
47
48
|
If you use a different monitoring service that you'd like to see supported, feel free to submit an issue. Better yet, pull requests are more than welcome!
|
48
49
|
|
@@ -51,7 +52,7 @@ Note that you'll need the gem for your monitor installed and configured for your
|
|
51
52
|
## Configuration
|
52
53
|
Temescal provides several configuration options for you. You can set these options when configuring the middleware for your application.
|
53
54
|
|
54
|
-
`monitors` to set the monitors you'd like to use with Temescal. It takes symbols of monitor names (currently `:airbrake`, `:bugsnag`, and `:
|
55
|
+
`monitors` to set the monitors you'd like to use with Temescal. It takes symbols of monitor names (currently `:airbrake`, `:bugsnag`, `:new_relic`, and `:honeybadger`).
|
55
56
|
|
56
57
|
`raise_errors` to set whether you'd like to override Temescal and raise all errors without rendering a Temescal response. Set to `true` to enable.
|
57
58
|
|
@@ -10,6 +10,9 @@ module Temescal
|
|
10
10
|
# Public: Setter for raise_errors option.
|
11
11
|
attr_writer :raise_errors
|
12
12
|
|
13
|
+
# Public: Setter for meta_key option.
|
14
|
+
attr_writer :meta_key
|
15
|
+
|
13
16
|
# Public: Getter/Setter for default JSON message.
|
14
17
|
attr_accessor :default_message
|
15
18
|
|
@@ -53,6 +56,13 @@ module Temescal
|
|
53
56
|
@ignored_errors = errors.flatten
|
54
57
|
end
|
55
58
|
|
59
|
+
# Public: Getter for meta_key option.
|
60
|
+
#
|
61
|
+
# Returns the meta_key option or simply "meta" if null.
|
62
|
+
def meta_key
|
63
|
+
@meta_key || "meta"
|
64
|
+
end
|
65
|
+
|
56
66
|
private
|
57
67
|
|
58
68
|
# Private: Converts a snake cased Symbol to a camel cased String.
|
data/lib/temescal/error.rb
CHANGED
data/lib/temescal/monitors.rb
CHANGED
@@ -41,5 +41,15 @@ module Temescal
|
|
41
41
|
::Bugsnag.notify exception
|
42
42
|
end
|
43
43
|
end
|
44
|
+
|
45
|
+
# Public: Reporting strategy for Honeybadger.
|
46
|
+
class Honeybadger < MonitorsStrategy
|
47
|
+
# Public: Reports an exception to Honeybadger.
|
48
|
+
#
|
49
|
+
# exception - The caught exception.
|
50
|
+
def self.report(exception)
|
51
|
+
::Honeybadger.notify exception
|
52
|
+
end
|
53
|
+
end
|
44
54
|
end
|
45
55
|
end
|
data/lib/temescal/response.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "json"
|
2
2
|
|
3
3
|
module Temescal
|
4
4
|
module Response
|
@@ -11,7 +11,7 @@ module Temescal
|
|
11
11
|
def self.build(error)
|
12
12
|
[
|
13
13
|
{
|
14
|
-
|
14
|
+
$_temescal_configuration.meta_key => {
|
15
15
|
status: error.status,
|
16
16
|
error: error.type,
|
17
17
|
message: error.message
|
data/lib/temescal/version.rb
CHANGED
@@ -7,8 +7,8 @@ class Temescal::Monitors::FooMonitor; end
|
|
7
7
|
describe Temescal::Configuration do
|
8
8
|
let(:config) { Temescal::Configuration.new }
|
9
9
|
|
10
|
-
|
11
|
-
it "
|
10
|
+
describe "#monitors=" do
|
11
|
+
it "adds a list of valid monitor classes to the monitors array from snake-cased arguments" do
|
12
12
|
config.monitors = :monitor, :fake_monitor, :foo_monitor
|
13
13
|
|
14
14
|
expect(config.monitors).to eq [
|
@@ -18,7 +18,7 @@ describe Temescal::Configuration do
|
|
18
18
|
]
|
19
19
|
end
|
20
20
|
|
21
|
-
it "
|
21
|
+
it "raises an error if a monitor strategy is invalid" do
|
22
22
|
expect { config.monitors = :foo }.to raise_error(NameError, /Foo is not a valid monitoring strategy/)
|
23
23
|
end
|
24
24
|
end
|
@@ -10,70 +10,70 @@ describe Temescal::Error do
|
|
10
10
|
$_temescal_configuration = Temescal::Configuration.new
|
11
11
|
end
|
12
12
|
|
13
|
-
|
14
|
-
it "
|
15
|
-
Temescal::Configuration.
|
13
|
+
describe "#message" do
|
14
|
+
it "returns the configured default message if it is set in the configuration" do
|
15
|
+
allow_any_instance_of(Temescal::Configuration).to receive(:default_message).and_return("Some other message.")
|
16
16
|
|
17
17
|
expect(error.message).to eq "Some other message."
|
18
18
|
end
|
19
19
|
|
20
|
-
it "
|
20
|
+
it "returns the exception's message if the default message is not configured" do
|
21
21
|
expect(error.message).to eq "Foobar"
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
it "
|
25
|
+
describe "#status" do
|
26
|
+
it "returns 404 if the exception is an ActiveRecord::RecordNotFound" do
|
27
27
|
exception = ActiveRecord::RecordNotFound.new
|
28
28
|
error = Temescal::Error.new(exception)
|
29
29
|
|
30
30
|
expect(error.status).to eq 404
|
31
31
|
end
|
32
32
|
|
33
|
-
it "
|
33
|
+
it "returns 404 if the exception is a Sinatra::NotFound" do
|
34
34
|
exception = Sinatra::NotFound.new
|
35
35
|
error = Temescal::Error.new(exception)
|
36
36
|
|
37
37
|
expect(error.status).to eq 404
|
38
38
|
end
|
39
39
|
|
40
|
-
it "
|
41
|
-
exception.
|
40
|
+
it "returns the exception's status code if assigned" do
|
41
|
+
allow(exception).to receive(:http_status).and_return(403)
|
42
42
|
|
43
43
|
expect(error.status).to eq 403
|
44
44
|
end
|
45
45
|
|
46
|
-
it "
|
46
|
+
it "returns 500 for all other exceptions" do
|
47
47
|
expect(error.status).to eq 500
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
|
52
|
-
it "
|
53
|
-
exception.
|
51
|
+
describe "#formatted" do
|
52
|
+
it "returns a String formatted for log output" do
|
53
|
+
allow(exception).to receive(:backtrace).and_return(["Line 1", "Line 2"])
|
54
54
|
|
55
55
|
expect(error.formatted).to eq "\nStandardError: Foobar\n Line 1\n Line 2\n\n"
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
|
60
|
-
it "
|
59
|
+
describe "#type" do
|
60
|
+
it "returns the exception's class name" do
|
61
61
|
expect(error.type).to eq "StandardError"
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
|
65
|
+
describe "#ignore?" do
|
66
66
|
before do
|
67
|
-
Temescal::Configuration.
|
67
|
+
allow_any_instance_of(Temescal::Configuration).to receive(:ignored_errors).and_return([TypeError])
|
68
68
|
end
|
69
69
|
|
70
|
-
it "
|
70
|
+
it "returns true if the exception type is configured as an ignored error" do
|
71
71
|
error = Temescal::Error.new(TypeError.new)
|
72
|
-
expect(error.ignore?).to
|
72
|
+
expect(error.ignore?).to be true
|
73
73
|
end
|
74
74
|
|
75
|
-
it "
|
76
|
-
expect(error.ignore?).to
|
75
|
+
it "returns false if the exception type is not an ignored error" do
|
76
|
+
expect(error.ignore?).to be false
|
77
77
|
end
|
78
78
|
end
|
79
79
|
end
|
@@ -12,7 +12,7 @@ describe Temescal::Middleware do
|
|
12
12
|
Temescal::Middleware.new(app)
|
13
13
|
end
|
14
14
|
|
15
|
-
it "
|
15
|
+
it "renders the application's response" do
|
16
16
|
code, _, _ = middleware.call env_for('http://foobar.com')
|
17
17
|
|
18
18
|
expect(code).to eq 200
|
@@ -21,8 +21,8 @@ describe Temescal::Middleware do
|
|
21
21
|
|
22
22
|
context "Bad response" do
|
23
23
|
before do
|
24
|
-
Temescal::Monitors::NewRelic.
|
25
|
-
$stderr.
|
24
|
+
allow(Temescal::Monitors::NewRelic).to receive(:report)
|
25
|
+
allow($stderr).to receive(:print)
|
26
26
|
|
27
27
|
# Travis automatically sets RACK_ENV=test
|
28
28
|
# Need to override for tests to run correctly.
|
@@ -38,27 +38,27 @@ describe Temescal::Middleware do
|
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
it "
|
41
|
+
it "responds with a 500 if the exception does not have a http_status attribute" do
|
42
42
|
code, _, _ = middleware.call env_for("http://foobar.com")
|
43
43
|
|
44
44
|
expect(code).to eq 500
|
45
45
|
end
|
46
46
|
|
47
|
-
it "
|
48
|
-
StandardError.
|
47
|
+
it "responds with the appropriate status if the exception has a http_status attribute" do
|
48
|
+
allow_any_instance_of(StandardError).to receive(:http_status).and_return(403)
|
49
49
|
|
50
50
|
code, _, _ = middleware.call env_for("http://foobar.com")
|
51
51
|
|
52
52
|
expect(code).to eq 403
|
53
53
|
end
|
54
54
|
|
55
|
-
it "
|
55
|
+
it "sets the correct content type header" do
|
56
56
|
_, headers, _ = middleware.call env_for("http://foobar.com")
|
57
57
|
|
58
58
|
expect(headers["Content-Type"]).to eq "application/json"
|
59
59
|
end
|
60
60
|
|
61
|
-
it "
|
61
|
+
it "renders a JSON response for the error" do
|
62
62
|
_, _, response = middleware.call env_for("http://foobar.com")
|
63
63
|
|
64
64
|
json = JSON.parse(response.first)["meta"]
|
@@ -67,20 +67,20 @@ describe Temescal::Middleware do
|
|
67
67
|
expect(json["message"]).to eq "Foobar"
|
68
68
|
end
|
69
69
|
|
70
|
-
it "
|
70
|
+
it "logs the error" do
|
71
71
|
expect($stderr).to receive(:print).with(an_instance_of String)
|
72
72
|
|
73
73
|
middleware.call env_for("http://foobar.com")
|
74
74
|
end
|
75
75
|
|
76
|
-
it "
|
76
|
+
it "reports the error to the specified monitors" do
|
77
77
|
expect(Temescal::Monitors::NewRelic).to receive(:report).with(an_instance_of StandardError)
|
78
78
|
|
79
79
|
middleware.call env_for("http://foobar.com")
|
80
80
|
end
|
81
81
|
|
82
82
|
context "with default_message set" do
|
83
|
-
it "
|
83
|
+
it "builds a response with the specified message instead of the exception message" do
|
84
84
|
middleware = Temescal::Middleware.new(app) do |config|
|
85
85
|
config.default_message = "An error has occured - we'll get on it right away!"
|
86
86
|
end
|
@@ -93,7 +93,7 @@ describe Temescal::Middleware do
|
|
93
93
|
end
|
94
94
|
|
95
95
|
context "with a Sinatra::NotFound error" do
|
96
|
-
it "
|
96
|
+
it "builds a response with a 404 status code" do
|
97
97
|
app = ->(env) { raise Sinatra::NotFound.new }
|
98
98
|
middleware = Temescal::Middleware.new(app)
|
99
99
|
|
@@ -104,7 +104,7 @@ describe Temescal::Middleware do
|
|
104
104
|
end
|
105
105
|
|
106
106
|
context "with an ActiveRecord::RecordNotFound error" do
|
107
|
-
it "
|
107
|
+
it "builds a response with a 404 status code" do
|
108
108
|
app = ->(env) { raise ActiveRecord::RecordNotFound.new }
|
109
109
|
middleware = Temescal::Middleware.new(app)
|
110
110
|
|
@@ -122,23 +122,39 @@ describe Temescal::Middleware do
|
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
|
-
it "
|
125
|
+
it "does not log an ignored error type" do
|
126
126
|
expect($stderr).to_not receive(:print).with(an_instance_of String)
|
127
127
|
|
128
128
|
middleware.call env_for("http://foobar.com")
|
129
129
|
end
|
130
130
|
|
131
|
-
it "
|
131
|
+
it "does not report an ignored error type" do
|
132
132
|
expect(Temescal::Monitors::NewRelic).to_not receive(:report).with(an_instance_of StandardError)
|
133
133
|
|
134
134
|
middleware.call env_for("http://foobar.com")
|
135
135
|
end
|
136
136
|
end
|
137
|
+
|
138
|
+
context "with custom meta key set" do
|
139
|
+
let(:middleware) do
|
140
|
+
Temescal::Middleware.new(app) do |config|
|
141
|
+
config.meta_key = "not_meta"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
it "builds a response with the custom key" do
|
146
|
+
_, _, response = middleware.call env_for("http://foobar.com")
|
147
|
+
|
148
|
+
response = JSON.parse(response.first)
|
149
|
+
|
150
|
+
expect(response["not_meta"]).to_not be_nil
|
151
|
+
end
|
152
|
+
end
|
137
153
|
end
|
138
154
|
|
139
155
|
context "Override middleware to raise exception" do
|
140
156
|
before do
|
141
|
-
$stderr.
|
157
|
+
allow($stderr).to receive(:print)
|
142
158
|
end
|
143
159
|
|
144
160
|
let(:app) { ->(env) { raise StandardError.new("Foobar") } }
|
@@ -149,7 +165,7 @@ describe Temescal::Middleware do
|
|
149
165
|
end
|
150
166
|
end
|
151
167
|
|
152
|
-
it "
|
168
|
+
it "raises the error" do
|
153
169
|
expect { middleware.call env_for("http://foobar.com") }.to raise_error StandardError
|
154
170
|
end
|
155
171
|
end
|
@@ -4,34 +4,52 @@ describe Temescal::Monitors do
|
|
4
4
|
let(:exception) { StandardError.new }
|
5
5
|
|
6
6
|
context "MonitorsStrategy" do
|
7
|
-
|
8
|
-
|
7
|
+
describe '.report' do
|
8
|
+
it "raises an error" do
|
9
|
+
expect { Temescal::Monitors::MonitorsStrategy.report(exception) }.to raise_error(NotImplementedError)
|
10
|
+
end
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
12
14
|
context "Airbrake" do
|
13
|
-
|
14
|
-
Airbrake
|
15
|
+
describe '.report' do
|
16
|
+
it "sends the exception to Airbrake" do
|
17
|
+
allow(Airbrake).to receive(:send_notice)
|
15
18
|
|
16
|
-
|
19
|
+
expect(Airbrake).to receive(:notify).with(exception)
|
17
20
|
|
18
|
-
|
21
|
+
Temescal::Monitors::Airbrake.report exception
|
22
|
+
end
|
19
23
|
end
|
20
24
|
end
|
21
25
|
|
22
26
|
context "NewRelic" do
|
23
|
-
|
24
|
-
|
27
|
+
describe '.report' do
|
28
|
+
it "sends the exception to New Relic" do
|
29
|
+
expect(NewRelic::Agent).to receive(:notice_error).with(exception)
|
25
30
|
|
26
|
-
|
31
|
+
Temescal::Monitors::NewRelic.report exception
|
32
|
+
end
|
27
33
|
end
|
28
34
|
end
|
29
35
|
|
30
36
|
context 'Bugsnag' do
|
31
|
-
|
32
|
-
|
37
|
+
describe '.report' do
|
38
|
+
it "sends the exception to Bugsnag" do
|
39
|
+
expect(Bugsnag).to receive(:notify).with(exception)
|
33
40
|
|
34
|
-
|
41
|
+
Temescal::Monitors::Bugsnag.report exception
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'Honeybadger' do
|
47
|
+
describe '.report' do
|
48
|
+
it "sends the exception to Honeybadger" do
|
49
|
+
expect(Honeybadger).to receive(:notify).with(exception)
|
50
|
+
|
51
|
+
Temescal::Monitors::Honeybadger.report exception
|
52
|
+
end
|
35
53
|
end
|
36
54
|
end
|
37
55
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -3,7 +3,7 @@ if ENV["CI"]
|
|
3
3
|
Coveralls.wear!
|
4
4
|
else
|
5
5
|
require "awesome_print"
|
6
|
-
require "pry-
|
6
|
+
require "pry-byebug"
|
7
7
|
|
8
8
|
require "simplecov"
|
9
9
|
SimpleCov.start
|
@@ -14,6 +14,7 @@ require "rack"
|
|
14
14
|
require "airbrake"
|
15
15
|
require "newrelic_rpm"
|
16
16
|
require "bugsnag"
|
17
|
+
require "honeybadger"
|
17
18
|
|
18
19
|
require "active_record"
|
19
20
|
require "sinatra"
|
@@ -21,7 +22,6 @@ require "sinatra"
|
|
21
22
|
require "temescal"
|
22
23
|
|
23
24
|
RSpec.configure do |config|
|
24
|
-
config.treat_symbols_as_metadata_keys_with_true_values = true
|
25
25
|
config.run_all_when_everything_filtered = true
|
26
26
|
config.filter_run :focus
|
27
27
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: temescal
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Todd Bealmear
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -81,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
81
81
|
version: '0'
|
82
82
|
requirements: []
|
83
83
|
rubyforge_project:
|
84
|
-
rubygems_version: 2.2.
|
84
|
+
rubygems_version: 2.2.2
|
85
85
|
signing_key:
|
86
86
|
specification_version: 4
|
87
87
|
summary: Rack Middleware for gracefully handling exceptions for JSON APIs.
|