airbrake 3.1.6 → 3.1.7
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.
- data/CHANGELOG +116 -0
- data/LICENSE +61 -0
- data/README.md +28 -478
- data/README_FOR_HEROKU_ADDON.md +13 -5
- data/Rakefile +26 -103
- data/TESTED_AGAINST +6 -0
- data/airbrake.gemspec +13 -14
- data/features/metal.feature +27 -12
- data/features/rack.feature +59 -59
- data/features/rails.feature +79 -100
- data/features/rails_with_js_notifier.feature +9 -21
- data/features/rake.feature +6 -4
- data/features/sinatra.feature +32 -6
- data/features/step_definitions/file_steps.rb +4 -0
- data/features/step_definitions/rack_steps.rb +9 -5
- data/features/step_definitions/rails_application_steps.rb +46 -278
- data/features/step_definitions/rake_steps.rb +16 -11
- data/features/support/airbrake_shim.rb.template +0 -2
- data/features/support/aruba.rb +5 -0
- data/features/support/env.rb +12 -6
- data/features/support/rails.rb +30 -73
- data/features/support/rake/Rakefile +1 -2
- data/features/user_informer.feature +12 -19
- data/generators/airbrake/airbrake_generator.rb +1 -1
- data/lib/airbrake.rb +9 -8
- data/lib/airbrake/cli/project_factory.rb +6 -3
- data/lib/airbrake/configuration.rb +7 -0
- data/lib/airbrake/notice.rb +52 -3
- data/lib/airbrake/rack.rb +16 -7
- data/lib/airbrake/rails/action_controller_catcher.rb +5 -3
- data/lib/airbrake/rails/controller_methods.rb +6 -6
- data/lib/airbrake/rails/error_lookup.rb +4 -2
- data/lib/airbrake/rails/javascript_notifier.rb +7 -3
- data/lib/airbrake/rails/middleware.rb +65 -0
- data/lib/airbrake/rails3_tasks.rb +16 -21
- data/lib/airbrake/railtie.rb +9 -16
- data/lib/airbrake/rake_handler.rb +2 -2
- data/lib/airbrake/sender.rb +57 -6
- data/lib/airbrake/shared_tasks.rb +24 -11
- data/lib/airbrake/sinatra.rb +34 -0
- data/lib/airbrake/user_informer.rb +9 -0
- data/lib/airbrake/version.rb +1 -1
- data/lib/rails/generators/airbrake/airbrake_generator.rb +10 -10
- data/{test/airbrake_2_3.xsd → resources/airbrake_2_4.xsd} +1 -0
- data/resources/airbrake_3_0.json +52 -0
- data/test/catcher_test.rb +198 -240
- data/test/configuration_test.rb +2 -0
- data/test/helper.rb +123 -53
- data/test/notice_test.rb +45 -1
- data/test/sender_test.rb +63 -32
- metadata +60 -79
- data/MIT-LICENSE +0 -22
- data/SUPPORTED_RAILS_VERSIONS +0 -38
- data/TESTING.md +0 -41
- data/features/step_definitions/metal_steps.rb +0 -23
- data/features/support/terminal.rb +0 -107
- data/lib/airbrake/extensions/blank.rb +0 -73
- data/lib/airbrake/rails/middleware/exceptions_catcher.rb +0 -33
@@ -14,11 +14,11 @@ namespace :airbrake do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
AirbrakeTasks.deploy(:rails_env => ENV['TO'],
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
17
|
+
:scm_revision => ENV['REVISION'],
|
18
|
+
:scm_repository => ENV['REPO'],
|
19
|
+
:local_username => ENV['USER'],
|
20
|
+
:api_key => ENV['API_KEY'],
|
21
|
+
:dry_run => ENV['DRY_RUN'])
|
22
22
|
end
|
23
23
|
|
24
24
|
task :log_stdout do
|
@@ -30,15 +30,28 @@ namespace :airbrake do
|
|
30
30
|
desc "Install Heroku deploy notifications addon"
|
31
31
|
task :add_deploy_notification => [:environment] do
|
32
32
|
|
33
|
-
def
|
34
|
-
`heroku config
|
33
|
+
def get_heroku_vars
|
34
|
+
config = `heroku config --shell`
|
35
|
+
array_of_vars = config.split.map do |var|
|
36
|
+
var.partition("=").tap {|part| part.delete_at(1)}
|
37
|
+
end.flatten
|
38
|
+
@heroku_vars = Hash[*array_of_vars]
|
35
39
|
end
|
36
40
|
|
37
|
-
|
38
|
-
heroku_api_key = heroku_var("(hoptoad|airbrake)_api_key").split.find {|x| x unless x.blank?} ||
|
39
|
-
Airbrake.configuration.api_key
|
41
|
+
get_heroku_vars
|
40
42
|
|
41
|
-
|
43
|
+
heroku_rails_env = @heroku_vars["RAILS_ENV"] || ENV["RAILS_ENV"] || "production"
|
44
|
+
heroku_api_key = @heroku_vars["AIRBRAKE_API_KEY"] || Airbrake.configuration.api_key || ENV["AIRBRAKE_API_KEY"]
|
45
|
+
heroku_app = ENV["HEROKU_APP"]
|
46
|
+
repo = `git config --get remote.origin.url` || ENV["REPO"]
|
47
|
+
|
48
|
+
command = %Q(heroku addons:add deployhooks:http --url="http://airbrake.io/deploys.txt?api_key=#{heroku_api_key})
|
49
|
+
command << "&deploy[local_username]={{user}}"
|
50
|
+
command << "&deploy[scm_revision]={{head_long}}"
|
51
|
+
command << "&deploy[rails_env]=#{heroku_rails_env}" if heroku_rails_env
|
52
|
+
command << "&deploy[scm_repository]=#{repo}" if repo
|
53
|
+
command << '"'
|
54
|
+
command << " --app=#{heroku_app}" if heroku_app
|
42
55
|
|
43
56
|
puts "\nRunning:\n#{command}\n"
|
44
57
|
puts `#{command}`
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Airbrake
|
2
|
+
# Middleware for Sinatra applications. Any errors raised by the upstream
|
3
|
+
# application will be delivered to Airbrake and re-raised.
|
4
|
+
|
5
|
+
# Synopsis:
|
6
|
+
|
7
|
+
# require 'sinatra'
|
8
|
+
# require 'airbrake'
|
9
|
+
|
10
|
+
# Airbrake.configure do |config|
|
11
|
+
# config.api_key = 'my api key'
|
12
|
+
# end
|
13
|
+
|
14
|
+
# use Airbrake::Sinatra
|
15
|
+
|
16
|
+
# get '/' do
|
17
|
+
# raise "Sinatra has left the building"
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# Use a standard Airbrake.configure call to configure your api key.
|
21
|
+
class Sinatra < Rack
|
22
|
+
|
23
|
+
def initialize(app)
|
24
|
+
super
|
25
|
+
Airbrake.configuration.environment_name = "#{app.settings.environment}"
|
26
|
+
Airbrake.configuration.framework = "Sinatra: #{::Sinatra::VERSION}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def framework_exception
|
30
|
+
@env['sinatra.error']
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -9,7 +9,12 @@ module Airbrake
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def call(env)
|
12
|
+
dup._call(env)
|
13
|
+
end
|
14
|
+
|
15
|
+
def _call(env)
|
12
16
|
status, headers, body = @app.call(env)
|
17
|
+
|
13
18
|
if env['airbrake.error_id'] && Airbrake.configuration.user_information
|
14
19
|
new_body = []
|
15
20
|
replace = replacement(env['airbrake.error_id'])
|
@@ -20,7 +25,11 @@ module Airbrake
|
|
20
25
|
headers['Content-Length'] = new_body.sum(&:bytesize).to_s
|
21
26
|
body = new_body
|
22
27
|
end
|
28
|
+
|
23
29
|
[status, headers, body]
|
30
|
+
|
31
|
+
ensure
|
32
|
+
body.close if body && body.respond_to?(:close) && $!
|
24
33
|
end
|
25
34
|
end
|
26
35
|
end
|
data/lib/airbrake/version.rb
CHANGED
@@ -49,7 +49,7 @@ class AirbrakeGenerator < Rails::Generators::Base
|
|
49
49
|
s = if options[:api_key]
|
50
50
|
"'#{options[:api_key]}'"
|
51
51
|
elsif options[:heroku]
|
52
|
-
"ENV['
|
52
|
+
"ENV['AIRBRAKE_API_KEY']"
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -59,31 +59,31 @@ class AirbrakeGenerator < Rails::Generators::Base
|
|
59
59
|
|
60
60
|
def determine_api_key
|
61
61
|
puts "Attempting to determine your API Key from Heroku..."
|
62
|
-
ENV['
|
63
|
-
if ENV['
|
62
|
+
ENV['AIRBRAKE_API_KEY'] = heroku_api_key
|
63
|
+
if ENV['AIRBRAKE_API_KEY'].blank?
|
64
64
|
puts "... Failed."
|
65
65
|
puts "WARNING: We were unable to detect the Airbrake API Key from your Heroku environment."
|
66
66
|
puts "Your Heroku application environment may not be configured correctly."
|
67
67
|
exit 1
|
68
68
|
else
|
69
69
|
puts "... Done."
|
70
|
-
puts "Heroku's Airbrake API Key is '#{ENV['
|
70
|
+
puts "Heroku's Airbrake API Key is '#{ENV['AIRBRAKE_API_KEY']}'"
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
74
|
def heroku_var(var,app_name = nil)
|
75
|
-
app = app_name ? "
|
76
|
-
`heroku config #{
|
75
|
+
app = app_name ? "-a #{app_name}" : ''
|
76
|
+
`heroku config:get #{var} #{app}`
|
77
77
|
end
|
78
78
|
|
79
79
|
def heroku_api_key
|
80
|
-
heroku_var("
|
80
|
+
heroku_var("AIRBRAKE_API_KEY",options[:app]).split.find {|x| x unless x.blank?}
|
81
81
|
end
|
82
82
|
|
83
83
|
def heroku?
|
84
84
|
options[:heroku] ||
|
85
|
-
system("grep
|
86
|
-
system("grep
|
85
|
+
system("grep AIRBRAKE_API_KEY config/initializers/airbrake.rb") ||
|
86
|
+
system("grep AIRBRAKE_API_KEY config/environment.rb")
|
87
87
|
end
|
88
88
|
|
89
89
|
def api_key_configured?
|
@@ -91,7 +91,7 @@ class AirbrakeGenerator < Rails::Generators::Base
|
|
91
91
|
end
|
92
92
|
|
93
93
|
def test_airbrake
|
94
|
-
puts run("rake airbrake:test
|
94
|
+
puts run("rake airbrake:test")
|
95
95
|
end
|
96
96
|
|
97
97
|
def plugin_is_present?
|
@@ -10,6 +10,7 @@
|
|
10
10
|
<xs:element name="request" type="request" minOccurs="0"/>
|
11
11
|
<xs:element name="server-environment" type="serverEnvironment"/>
|
12
12
|
<xs:element name="current-user" type="current-user" minOccurs="0"/>
|
13
|
+
<xs:element name="framework" type="xs:string" minOccurs="0"/>
|
13
14
|
</xs:all>
|
14
15
|
<xs:attribute name="version" type="xs:string" use="required"/>
|
15
16
|
</xs:complexType>
|
@@ -0,0 +1,52 @@
|
|
1
|
+
{
|
2
|
+
"type" : "object",
|
3
|
+
"additionalProperties" : false,
|
4
|
+
"properties" : {
|
5
|
+
"notifier" : {
|
6
|
+
"type" : "hash",
|
7
|
+
"required" : true,
|
8
|
+
"additionalProperties" : false,
|
9
|
+
"properties" : {
|
10
|
+
"name" : {"type" : "string", "required" : true},
|
11
|
+
"version" : {"type" : "string", "required" : true},
|
12
|
+
"url" : {"type" : "string", "required" : true}
|
13
|
+
}
|
14
|
+
},
|
15
|
+
"errors" : {
|
16
|
+
"type" : "array",
|
17
|
+
"required" : true,
|
18
|
+
"items" : {
|
19
|
+
"type" : [{
|
20
|
+
"type" : "hash",
|
21
|
+
"additionalProperties" : false,
|
22
|
+
"properties" : {
|
23
|
+
"backtrace" : {"type" : "array", "required" : true},
|
24
|
+
"type" : {"type" : "string", "required" : true},
|
25
|
+
"message" : {"type" : "string", "required" : true}
|
26
|
+
}
|
27
|
+
}]
|
28
|
+
}
|
29
|
+
},
|
30
|
+
"context" : {
|
31
|
+
"type" : "hash",
|
32
|
+
"additionalProperties" : false,
|
33
|
+
"properties" : {
|
34
|
+
"os" : {"type" : "string"},
|
35
|
+
"language" : {"type" : "string"},
|
36
|
+
"environment" : {"type" : "string"},
|
37
|
+
"version" : {"type" : "string"},
|
38
|
+
"url" : {"type" : "string"},
|
39
|
+
"rootDirectory" : {"type" : "string"},
|
40
|
+
"userId" : {"type" : "string"},
|
41
|
+
"userName" : {"type" : "string"},
|
42
|
+
"userEmail" : {"type" : "string"},
|
43
|
+
"component" : {"type" : "string"},
|
44
|
+
"action" : {"type" : "string"}
|
45
|
+
}
|
46
|
+
},
|
47
|
+
"environment" : {"type" : "hash"},
|
48
|
+
"session" : {"type" : "hash"},
|
49
|
+
"params" : {"type" : "hash"}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
data/test/catcher_test.rb
CHANGED
@@ -1,6 +1,23 @@
|
|
1
1
|
require File.expand_path '../helper', __FILE__
|
2
2
|
|
3
|
-
|
3
|
+
require 'airbrake/rails/controller_methods'
|
4
|
+
require 'airbrake/rails/middleware'
|
5
|
+
|
6
|
+
module ActionDispatch
|
7
|
+
class ShowExceptions
|
8
|
+
private
|
9
|
+
def public_path
|
10
|
+
"/null"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Silence logger
|
14
|
+
def logger
|
15
|
+
nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class ActionControllerCatcherTest < ActionDispatch::IntegrationTest
|
4
21
|
|
5
22
|
include DefinesConstants
|
6
23
|
|
@@ -8,6 +25,7 @@ class ActionControllerCatcherTest < Test::Unit::TestCase
|
|
8
25
|
super
|
9
26
|
reset_config
|
10
27
|
Airbrake.sender = CollectingSender.new
|
28
|
+
Airbrake.configuration.development_environments = []
|
11
29
|
define_constant('RAILS_ROOT', '/path/to/rails/root')
|
12
30
|
end
|
13
31
|
|
@@ -15,22 +33,17 @@ class ActionControllerCatcherTest < Test::Unit::TestCase
|
|
15
33
|
Airbrake.configuration.ignore << exception_class
|
16
34
|
end
|
17
35
|
|
18
|
-
def build_controller_class(&definition)
|
19
|
-
Class.new(ActionController::Base).tap do |klass|
|
20
|
-
klass.__send__(:include, Airbrake::Rails::ActionControllerCatcher)
|
21
|
-
klass.class_eval(&definition) if definition
|
22
|
-
define_constant('AirbrakeTestController', klass)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
36
|
def assert_sent_hash(hash, xpath)
|
27
37
|
hash.each do |key, value|
|
28
|
-
next if key.match(/^airbrake\./) # We added this key.
|
38
|
+
next if key.match(/^airbrake\./) || # We added this key.
|
39
|
+
hash[key].blank?
|
29
40
|
|
30
41
|
element_xpath = "#{xpath}/var[@key = '#{key}']"
|
31
42
|
if value.respond_to?(:to_hash)
|
32
43
|
assert_sent_hash value.to_hash, element_xpath
|
33
44
|
else
|
45
|
+
next if key == "action_dispatch.exception" # TODO: Rails 3.2 only - review
|
46
|
+
value.gsub!(/\d/,"") if key == "PATH_INFO" # TODO: Rails 3.2 only - review
|
34
47
|
assert_sent_element value, element_xpath
|
35
48
|
end
|
36
49
|
end
|
@@ -66,7 +79,8 @@ class ActionControllerCatcherTest < Test::Unit::TestCase
|
|
66
79
|
url << ":#{request.port}"
|
67
80
|
end
|
68
81
|
|
69
|
-
url << request.
|
82
|
+
url << request.fullpath.gsub(%r{\d},"") # TODO: Rails 3.2 only - review
|
83
|
+
|
70
84
|
url
|
71
85
|
end
|
72
86
|
|
@@ -83,251 +97,195 @@ class ActionControllerCatcherTest < Test::Unit::TestCase
|
|
83
97
|
Nokogiri::XML.parse(xml)
|
84
98
|
end
|
85
99
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
define_method(:index, &action)
|
92
|
-
def local_request?
|
93
|
-
local
|
94
|
-
end
|
95
|
-
end
|
96
|
-
if opts[:filters]
|
97
|
-
klass.filter_parameter_logging *opts[:filters]
|
98
|
-
end
|
99
|
-
if opts[:user_agent]
|
100
|
-
if opts[:request].respond_to?(:user_agent=)
|
101
|
-
opts[:request].user_agent = opts[:user_agent]
|
102
|
-
else
|
103
|
-
opts[:request].env["HTTP_USER_AGENT"] = opts[:user_agent]
|
104
|
-
end
|
105
|
-
end
|
106
|
-
if opts[:port]
|
107
|
-
opts[:request].port = opts[:port]
|
108
|
-
end
|
109
|
-
klass.consider_all_requests_local = opts[:all_local]
|
110
|
-
klass.local = opts[:local]
|
111
|
-
controller = klass.new
|
112
|
-
controller.stubs(:rescue_action_in_public_without_airbrake)
|
113
|
-
opts[:request].query_parameters = opts[:request].query_parameters.merge(opts[:params] || {})
|
114
|
-
opts[:request].session = ActionController::TestSession.new(opts[:session] || {})
|
115
|
-
# Prevents request.fullpath from crashing Rails in tests
|
116
|
-
opts[:request].env['REQUEST_URI'] = opts[:request].request_uri
|
117
|
-
controller.process(opts[:request], opts[:response])
|
118
|
-
controller
|
119
|
-
end
|
120
|
-
|
121
|
-
def process_action_with_manual_notification(args = {})
|
122
|
-
process_action(args) do
|
123
|
-
notify_airbrake(:error_message => 'fail')
|
124
|
-
# Rails will raise a template error if we don't render something
|
125
|
-
render :nothing => true
|
100
|
+
class AirbrakeTestController < ActionController::Base
|
101
|
+
begin
|
102
|
+
use ActionDispatch::ShowExceptions, ActionDispatch::PublicExceptions.new("/null")
|
103
|
+
rescue NameError
|
104
|
+
use ActionDispatch::ShowExceptions
|
126
105
|
end
|
127
|
-
end
|
128
|
-
|
129
|
-
def process_action_with_automatic_notification(args = {})
|
130
|
-
process_action(args) { raise "Hello" }
|
131
|
-
end
|
132
|
-
|
133
|
-
should "deliver notices from exceptions raised in public requests" do
|
134
|
-
process_action_with_automatic_notification
|
135
|
-
assert_caught_and_sent
|
136
|
-
end
|
137
|
-
|
138
|
-
should "not deliver notices from exceptions in local requests" do
|
139
|
-
process_action_with_automatic_notification(:local => true)
|
140
|
-
assert_caught_and_not_sent
|
141
|
-
end
|
142
|
-
|
143
|
-
should "not deliver notices from exceptions when all requests are local" do
|
144
|
-
process_action_with_automatic_notification(:all_local => true)
|
145
|
-
assert_caught_and_not_sent
|
146
|
-
end
|
147
|
-
|
148
|
-
should "not deliver notices from actions that don't raise" do
|
149
|
-
controller = process_action { render :text => 'Hello' }
|
150
|
-
assert_caught_and_not_sent
|
151
|
-
assert_equal 'Hello', controller.response.body
|
152
|
-
end
|
153
|
-
|
154
|
-
should "not deliver ignored exceptions raised by actions" do
|
155
|
-
ignore(RuntimeError)
|
156
|
-
process_action_with_automatic_notification
|
157
|
-
assert_caught_and_not_sent
|
158
|
-
end
|
159
|
-
|
160
|
-
should "deliver ignored exception raised manually" do
|
161
|
-
ignore(RuntimeError)
|
162
|
-
process_action_with_manual_notification
|
163
|
-
assert_caught_and_sent
|
164
|
-
end
|
165
|
-
|
166
|
-
should "deliver manually sent notices in public requests" do
|
167
|
-
process_action_with_manual_notification
|
168
|
-
assert_caught_and_sent
|
169
|
-
end
|
170
|
-
|
171
|
-
should "not deliver manually sent notices in local requests" do
|
172
|
-
process_action_with_manual_notification(:local => true)
|
173
|
-
assert_caught_and_not_sent
|
174
|
-
end
|
175
|
-
|
176
|
-
should "not deliver manually sent notices when all requests are local" do
|
177
|
-
process_action_with_manual_notification(:all_local => true)
|
178
|
-
assert_caught_and_not_sent
|
179
|
-
end
|
180
|
-
|
181
|
-
should "continue with default behavior after delivering an exception" do
|
182
|
-
controller = process_action_with_automatic_notification(:public => true)
|
183
|
-
# TODO: can we test this without stubbing?
|
184
|
-
assert_received(controller, :rescue_action_in_public_without_airbrake)
|
185
|
-
end
|
186
|
-
|
187
|
-
should "not create actions from Airbrake methods" do
|
188
|
-
controller = build_controller_class.new
|
189
|
-
assert_equal [], Airbrake::Rails::ActionControllerCatcher.instance_methods
|
190
|
-
end
|
191
|
-
|
192
|
-
should "ignore exceptions when user agent is being ignored by regular expression" do
|
193
|
-
Airbrake.configuration.ignore_user_agent_only = [/Ignored/]
|
194
|
-
process_action_with_automatic_notification(:user_agent => 'ShouldBeIgnored')
|
195
|
-
assert_caught_and_not_sent
|
196
|
-
end
|
197
|
-
|
198
|
-
should "ignore exceptions when user agent is being ignored by string" do
|
199
|
-
Airbrake.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
|
200
|
-
process_action_with_automatic_notification(:user_agent => 'IgnoredUserAgent')
|
201
|
-
assert_caught_and_not_sent
|
202
|
-
end
|
203
|
-
|
204
|
-
should "not ignore exceptions when user agent is not being ignored" do
|
205
|
-
Airbrake.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
|
206
|
-
process_action_with_automatic_notification(:user_agent => 'NonIgnoredAgent')
|
207
|
-
assert_caught_and_sent
|
208
|
-
end
|
209
|
-
|
210
|
-
should "send session data for manual notifications" do
|
211
|
-
data = { 'one' => 'two' }
|
212
|
-
process_action_with_manual_notification(:session => data)
|
213
|
-
assert_sent_hash data, "/notice/request/session"
|
214
|
-
end
|
215
|
-
|
216
|
-
should "send session data for automatic notification" do
|
217
|
-
data = { 'one' => 'two' }
|
218
|
-
process_action_with_automatic_notification(:session => data)
|
219
|
-
assert_sent_hash data, "/notice/request/session"
|
220
|
-
end
|
221
|
-
|
222
|
-
should "send request data for manual notification" do
|
223
|
-
params = { 'controller' => "airbrake_test", 'action' => "index" }
|
224
|
-
controller = process_action_with_manual_notification(:params => params)
|
225
|
-
assert_sent_request_info_for controller.request
|
226
|
-
end
|
227
106
|
|
228
|
-
|
229
|
-
params = { 'controller' => "airbrake_test", 'action' => "index" }
|
230
|
-
controller = process_action_with_manual_notification(:params => params, :port => 81)
|
231
|
-
assert_sent_request_info_for controller.request
|
232
|
-
end
|
107
|
+
use Airbrake::Rails::Middleware
|
233
108
|
|
234
|
-
|
235
|
-
params = { 'controller' => "airbrake_test", 'action' => "index" }
|
236
|
-
controller = process_action_with_automatic_notification(:params => params)
|
237
|
-
assert_sent_request_info_for controller.request
|
238
|
-
end
|
109
|
+
include Airbrake::Rails::ControllerMethods
|
239
110
|
|
240
|
-
|
241
|
-
params = { 'controller' => "airbrake_test", 'action' => "index" }
|
242
|
-
controller = process_action_with_automatic_notification(:params => params, :port => 81)
|
243
|
-
assert_sent_request_info_for controller.request
|
244
|
-
end
|
245
|
-
|
246
|
-
should "use standard rails logging filters on params and session and env" do
|
247
|
-
filtered_params = { "abc" => "123",
|
248
|
-
"def" => "456",
|
249
|
-
"ghi" => "[FILTERED]" }
|
250
|
-
filtered_session = { "abc" => "123",
|
251
|
-
"ghi" => "[FILTERED]" }
|
252
|
-
ENV['ghi'] = 'abc'
|
253
|
-
filtered_env = { 'ghi' => '[FILTERED]' }
|
254
|
-
filtered_cgi = { 'REQUEST_METHOD' => '[FILTERED]' }
|
255
|
-
|
256
|
-
process_action_with_automatic_notification(:filters => [:ghi, :request_method],
|
257
|
-
:params => { "abc" => "123",
|
258
|
-
"def" => "456",
|
259
|
-
"ghi" => "789" },
|
260
|
-
:session => { "abc" => "123",
|
261
|
-
"ghi" => "789" })
|
262
|
-
assert_sent_hash filtered_params, '/notice/request/params'
|
263
|
-
assert_sent_hash filtered_cgi, '/notice/request/cgi-data'
|
264
|
-
assert_sent_hash filtered_session, '/notice/request/session'
|
265
|
-
end
|
111
|
+
cattr_accessor :local
|
266
112
|
|
267
|
-
|
268
|
-
setup do
|
269
|
-
Airbrake.configuration.development_lookup = true
|
270
|
-
Airbrake.stubs(:build_lookup_hash_for).returns({ :awesome => 2 })
|
113
|
+
before_filter :set_session
|
271
114
|
|
272
|
-
|
273
|
-
|
115
|
+
def set_session
|
116
|
+
unless params.empty?
|
117
|
+
request.session = ActionController::TestSession.new(params[:session] || {})
|
118
|
+
end
|
274
119
|
end
|
275
120
|
|
276
|
-
|
277
|
-
|
278
|
-
|
121
|
+
def boom
|
122
|
+
raise "boom"
|
123
|
+
render :nothing => true
|
279
124
|
end
|
280
125
|
|
281
|
-
|
282
|
-
|
283
|
-
assert_match Airbrake.configuration.api_key.to_json, @response.body
|
284
|
-
assert_match ({ :awesome => 2 }).to_json, @response.body
|
126
|
+
def hello
|
127
|
+
render :text => "hello"
|
285
128
|
end
|
286
|
-
end
|
287
129
|
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
@controller = process_action_with_automatic_notification(:local => true)
|
293
|
-
@response = @controller.response
|
294
|
-
end
|
295
|
-
|
296
|
-
should "not append custom CSS and JS to response for a local error" do
|
297
|
-
assert_no_match /text\/css/, @response.body
|
298
|
-
assert_no_match /text\/javascript/, @response.body
|
130
|
+
def manual_airbrake
|
131
|
+
notify_airbrake(:error_message => "fail")
|
132
|
+
render :nothing => true
|
299
133
|
end
|
300
|
-
end
|
301
134
|
|
302
|
-
|
303
|
-
hash_data = {:key => :value}
|
135
|
+
protected
|
304
136
|
|
305
|
-
|
306
|
-
|
307
|
-
session.stubs(:to_hash).returns(hash_data)
|
308
|
-
|
309
|
-
process_action_with_automatic_notification
|
310
|
-
assert_received(session, :to_hash)
|
311
|
-
assert_received(session, :data) { |expect| expect.never }
|
312
|
-
assert_caught_and_sent
|
313
|
-
end
|
314
|
-
|
315
|
-
should "call session.data if session.to_hash is undefined" do
|
316
|
-
hash_data = {:key => :value}
|
317
|
-
|
318
|
-
session = ActionController::TestSession.new
|
319
|
-
ActionController::TestSession.stubs(:new).returns(session)
|
320
|
-
session.stubs(:data).returns(hash_data)
|
321
|
-
if session.respond_to?(:to_hash)
|
322
|
-
class << session
|
323
|
-
undef to_hash
|
324
|
-
end
|
137
|
+
def airbrake_local_request?
|
138
|
+
@@local
|
325
139
|
end
|
326
|
-
|
327
|
-
process_action_with_automatic_notification
|
328
|
-
assert_received(session, :to_hash) { |expect| expect.never }
|
329
|
-
assert_received(session, :data) { |expect| expect.at_least_once }
|
330
|
-
assert_caught_and_sent
|
331
140
|
end
|
332
141
|
|
142
|
+
setup do
|
143
|
+
Airbrake.configuration.development_environments = []
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
should "deliver notices from exceptions raised in public requests" do
|
148
|
+
@app = AirbrakeTestController.action(:boom)
|
149
|
+
get '/'
|
150
|
+
assert_caught_and_sent
|
151
|
+
end
|
152
|
+
|
153
|
+
should "not deliver notices from exceptions in development environments" do
|
154
|
+
Airbrake.configuration.development_environments = ["test"]
|
155
|
+
Airbrake.configuration.environment_name = "test"
|
156
|
+
@app = AirbrakeTestController.action(:boom)
|
157
|
+
get '/'
|
158
|
+
assert_caught_and_not_sent
|
159
|
+
end
|
160
|
+
|
161
|
+
should "not deliver notices from actions that don't raise" do
|
162
|
+
@app = AirbrakeTestController.action(:hello)
|
163
|
+
get '/'
|
164
|
+
assert_caught_and_not_sent
|
165
|
+
assert_equal 'hello', response.body
|
166
|
+
end
|
167
|
+
|
168
|
+
should "not deliver ignored exceptions raised by actions" do
|
169
|
+
@app = AirbrakeTestController.action(:boom)
|
170
|
+
ignore(RuntimeError)
|
171
|
+
get '/'
|
172
|
+
assert_caught_and_not_sent
|
173
|
+
end
|
174
|
+
|
175
|
+
should "deliver ignored exception raised manually" do
|
176
|
+
@app = AirbrakeTestController.action(:manual_airbrake)
|
177
|
+
ignore(RuntimeError)
|
178
|
+
get '/'
|
179
|
+
assert_caught_and_sent
|
180
|
+
end
|
181
|
+
|
182
|
+
should "not deliver manually sent notices in local requests" do
|
183
|
+
AirbrakeTestController.local = true
|
184
|
+
@app = AirbrakeTestController.action(:manual_airbrake)
|
185
|
+
get '/'
|
186
|
+
assert_caught_and_not_sent
|
187
|
+
AirbrakeTestController.local = false
|
188
|
+
end
|
189
|
+
|
190
|
+
should "not create actions from Airbrake methods" do
|
191
|
+
Airbrake::Rails::ControllerMethods.instance_methods.each do |method|
|
192
|
+
assert !(AirbrakeTestController.new.action_methods.include?(method))
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
should "ignore exceptions when user agent is being ignored by regular expression" do
|
197
|
+
Airbrake.configuration.ignore_user_agent_only = [/Ignored/]
|
198
|
+
@app = AirbrakeTestController.action(:boom)
|
199
|
+
get "/", {}, {"HTTP_USER_AGENT" => "ShouldBeIgnored"}
|
200
|
+
assert_caught_and_not_sent
|
201
|
+
end
|
202
|
+
|
203
|
+
should "ignore exceptions when user agent is being ignored by string" do
|
204
|
+
Airbrake.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
|
205
|
+
@app = AirbrakeTestController.action(:boom)
|
206
|
+
get "/", {}, {"HTTP_USER_AGENT" => "IgnoredUserAgent"}
|
207
|
+
assert_caught_and_not_sent
|
208
|
+
end
|
209
|
+
|
210
|
+
should "not ignore exceptions when user agent is not being ignored" do
|
211
|
+
Airbrake.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
|
212
|
+
@app = AirbrakeTestController.action(:boom)
|
213
|
+
get "/", {}, {"HTTP_USER_AGENT" => "NonIgnoredAgent"}
|
214
|
+
assert_caught_and_sent
|
215
|
+
end
|
216
|
+
|
217
|
+
should "send session data for manual notifications" do
|
218
|
+
@app = AirbrakeTestController.action(:manual_airbrake)
|
219
|
+
data = { 'one' => 'two' }
|
220
|
+
get "/", :session => data
|
221
|
+
assert_sent_hash data, "/notice/request/session"
|
222
|
+
end
|
223
|
+
|
224
|
+
should "send request data for manual notification" do
|
225
|
+
params = { 'controller' => "airbrake_test", 'action' => "index" }
|
226
|
+
@app = AirbrakeTestController.action(:manual_airbrake)
|
227
|
+
get "/", params
|
228
|
+
assert_sent_request_info_for @request
|
229
|
+
end
|
230
|
+
|
231
|
+
should "send request data for manual notification with non-standard port" do
|
232
|
+
params = { 'controller' => "airbrake_test", 'action' => "index" }
|
233
|
+
@app = AirbrakeTestController.action(:manual_airbrake)
|
234
|
+
get "/", params, {"SERVER_PORT" => 81}
|
235
|
+
assert_sent_request_info_for @request
|
236
|
+
end
|
237
|
+
|
238
|
+
should "send request data for automatic notification" do
|
239
|
+
params = { 'controller' => "airbrake_test", 'action' => "index" }
|
240
|
+
@app = AirbrakeTestController.action(:boom)
|
241
|
+
get "/", params
|
242
|
+
assert_sent_request_info_for @request
|
243
|
+
end
|
244
|
+
|
245
|
+
should "send request data for automatic notification with non-standard port" do
|
246
|
+
params = { 'controller' => "airbrake_test", 'action' => "index" }
|
247
|
+
@app = AirbrakeTestController.action(:boom)
|
248
|
+
get "/", params, {"SERVER_PORT" => 81}
|
249
|
+
assert_sent_request_info_for @request
|
250
|
+
assert_sent_element 81, "/notice/request/cgi-data/var[@key = 'SERVER_PORT']"
|
251
|
+
end
|
252
|
+
|
253
|
+
# should "call session.to_hash if available" do
|
254
|
+
# hash_data = {:key => :value}
|
255
|
+
|
256
|
+
# session = ActionController::TestSession.new
|
257
|
+
# ActionController::TestSession.stubs(:new).returns(session)
|
258
|
+
# session.stubs(:to_hash).returns(hash_data)
|
259
|
+
|
260
|
+
# Airbrake.configuration.environment_name = "production"
|
261
|
+
|
262
|
+
# @app = AirbrakeTestController.action(:boom)
|
263
|
+
# get '/'
|
264
|
+
|
265
|
+
# assert_received(session, :to_hash)
|
266
|
+
# assert_received(session, :data) { |expect| expect.never }
|
267
|
+
# assert_caught_and_sent
|
268
|
+
# end
|
269
|
+
|
270
|
+
# should "call session.data if session.to_hash is undefined" do
|
271
|
+
# hash_data = {:key => :value}
|
272
|
+
|
273
|
+
# session = ActionController::TestSession.new
|
274
|
+
# ActionController::TestSession.stubs(:new).returns(session)
|
275
|
+
# session.stubs(:data).returns(hash_data)
|
276
|
+
# if session.respond_to?(:to_hash)
|
277
|
+
# class << session
|
278
|
+
# undef to_hash
|
279
|
+
# end
|
280
|
+
# end
|
281
|
+
|
282
|
+
# Airbrake.configuration.environment_name = "production"
|
283
|
+
|
284
|
+
# @app = AirbrakeTestController.action(:boom)
|
285
|
+
# get '/'
|
286
|
+
|
287
|
+
# assert_received(session, :to_hash) { |expect| expect.never }
|
288
|
+
# assert_received(session, :data) { |expect| expect.at_least_once }
|
289
|
+
# assert_caught_and_sent
|
290
|
+
# end
|
333
291
|
end
|