honeybadger 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- honeybadger (1.2.1)
4
+ honeybadger (1.3.0)
5
5
  activesupport
6
6
  json
7
7
 
data/README.md CHANGED
@@ -124,22 +124,27 @@ this rake task (from RAILS_ROOT):
124
124
  If everything is configured properly, that task will send a notice to Honeybadger
125
125
  which will be visible immediately.
126
126
 
127
- ## User Tracking
127
+ ## Sending custom data
128
128
 
129
- Honeybadger will automatically try to associate errors and notices with the current user.
129
+ Honeybadger allows you to send custom data using `Honeybadger.context`.
130
+ Here's an example of sending some user-specific information in a Rails
131
+ `before_filter` call:
130
132
 
131
- By default, it tries to call `current_user` when rescuing exceptions in ActionController.
132
- If you want to use a different method, you may do so in the honeybadger initializer:
133
-
134
- Honeybadger.configure do |config|
135
- ...
136
- # The current user method to call for errors rescued in ActionController
137
- config.current_user_method = :a_controller_method_which_returns_the_user
133
+ before_filter do
134
+ Honeybadger.context({
135
+ user_id: current_user.id,
136
+ user_email: current_user.email
137
+ }) if current_user
138
138
  end
139
139
 
140
- Honeybadger assumes that the object returned by `current_user` will respond to `#id`,
141
- and will optionally include the user's email address if the user object also responds
142
- to `#email`.
140
+ Now, whenever an error occurs, Honeybadger will display the affected
141
+ user's id and email address, if available.
142
+
143
+ Subsequent calls to `context` will merge the existing hash with any new
144
+ data, so you can effectively build up context throughout your
145
+ request's life cycle. Honeybadger will discard the data when a
146
+ request completes, so that the next request will start with a blank
147
+ slate.
143
148
 
144
149
  ## Going beyond exceptions
145
150
 
@@ -151,7 +156,7 @@ controllers:
151
156
  params = {
152
157
  # params that you pass to a method that can throw an exception
153
158
  }
154
- my_unpredicable_method(params)
159
+ my_unpredicable_method(*params)
155
160
  rescue => e
156
161
  Honeybadger.notify(
157
162
  :error_class => "Special Error",
@@ -175,7 +180,8 @@ Honeybadger merges the hash you pass with these default options:
175
180
  :error_message => 'Notification',
176
181
  :backtrace => caller,
177
182
  :parameters => {},
178
- :session => {}
183
+ :session => {},
184
+ :context => {}
179
185
  }
180
186
 
181
187
  You can override any of those parameters.
@@ -288,6 +294,8 @@ originally by Thoughtbot, Inc.
288
294
 
289
295
  Thank you to Thoughtbot and all of the Airbrake contributors!
290
296
 
297
+ The nifty custom data (`Honeybadger.context()`) feature was inspired by Exceptional.
298
+
291
299
  ## License
292
300
 
293
301
  Honeybadger is Copyright 2012 © Honeybadger. It is free software, and
data/Rakefile CHANGED
@@ -196,7 +196,7 @@ end
196
196
 
197
197
  desc "Update supported versions: Run this to pull down latest rails versions from rubygems"
198
198
  task :update_supported_versions do
199
- down_to = Gem::Version.new('3.0.0')
199
+ down_to = Gem::Version.new('2.3.14')
200
200
  versions = JSON.parse `curl https://rubygems.org/api/v1/versions/rails.json 2> /dev/null`
201
201
  supported_versions = versions.map { |v| Gem::Version.new(v['number']) }.reject { |v| v < down_to || v.prerelease? }.sort
202
202
  `echo '#{supported_versions.join("\n")}' > SUPPORTED_RAILS_VERSIONS`
@@ -1,3 +1,4 @@
1
+ 2.3.14
1
2
  3.0.0
2
3
  3.0.1
3
4
  3.0.2
data/honeybadger.gemspec CHANGED
@@ -4,8 +4,8 @@ Gem::Specification.new do |s|
4
4
  s.rubygems_version = '1.3.5'
5
5
 
6
6
  s.name = 'honeybadger'
7
- s.version = '1.2.1'
8
- s.date = '2012-09-29'
7
+ s.version = '1.3.0'
8
+ s.date = '2012-10-02'
9
9
 
10
10
  s.summary = "Error reports you can be happy about."
11
11
  s.description = "Make managing application errors a more pleasant experience."
data/lib/honeybadger.rb CHANGED
@@ -19,7 +19,7 @@ require 'honeybadger/sender'
19
19
  require 'honeybadger/railtie' if defined?(Rails::Railtie)
20
20
 
21
21
  module Honeybadger
22
- VERSION = '1.2.1'
22
+ VERSION = '1.3.0'
23
23
  LOG_PREFIX = "** [Honeybadger] "
24
24
 
25
25
  HEADERS = {
@@ -105,6 +105,7 @@ module Honeybadger
105
105
  # :rack_env - The Rack environment.
106
106
  # :session - The contents of the user's session.
107
107
  # :environment_name - The application environment name.
108
+ # :context - Custom hash to send
108
109
  #
109
110
  # Returns exception ID from Honeybadger on success, false on failure
110
111
  def self.notify(exception, options = {})
@@ -135,6 +136,16 @@ module Honeybadger
135
136
  result
136
137
  end
137
138
 
139
+ def self.context(hash = {})
140
+ Thread.current[:honeybadger_context] ||= {}
141
+ Thread.current[:honeybadger_context].merge!(hash)
142
+ self
143
+ end
144
+
145
+ def self.clear!
146
+ Thread.current[:honeybadger_context] = nil
147
+ end
148
+
138
149
  private
139
150
 
140
151
  def self.send_notice(notice)
@@ -84,9 +84,6 @@ module Honeybadger
84
84
  # The framework Honeybadger is configured to use
85
85
  attr_accessor :framework
86
86
 
87
- # The current user method to call for errors rescued in ActionController
88
- attr_accessor :current_user_method
89
-
90
87
  # Should Honeybadger catch exceptions from Rake tasks?
91
88
  # (boolean or nil; set to nil to catch exceptions when rake isn't running from a terminal; default is nil)
92
89
  attr_accessor :rescue_rake_exceptions
@@ -144,7 +141,6 @@ module Honeybadger
144
141
  @framework = 'Standalone'
145
142
  @user_information = 'Honeybadger Error {{error_id}}'
146
143
  @rescue_rake_exceptions = nil
147
- @current_user_method = :current_user
148
144
  @source_extract_radius = 2
149
145
  end
150
146
 
@@ -263,6 +259,10 @@ module Honeybadger
263
259
  File.expand_path(File.join("..", "..", "..", "resources", "ca-bundle.crt"), __FILE__)
264
260
  end
265
261
 
262
+ # Stub deprecated current_user_method configuration option
263
+ # This should be removed completely once everyone has updated to > 1.2
264
+ def current_user_method=(null) ; end
265
+
266
266
  private
267
267
 
268
268
  # Private: Determines what port should we use for sending notices.
@@ -46,6 +46,9 @@ module Honeybadger
46
46
  # A hash of session data from the request
47
47
  attr_reader :session_data
48
48
 
49
+ # Additional contextual information (custom data)
50
+ attr_reader :context
51
+
49
52
  # The path to the project that caused the error (usually Rails.root)
50
53
  attr_reader :project_root
51
54
 
@@ -70,9 +73,6 @@ module Honeybadger
70
73
  # The host name where this error occurred (if any)
71
74
  attr_reader :hostname
72
75
 
73
- # The user affected by the exception, if available
74
- attr_reader :user
75
-
76
76
  def initialize(args)
77
77
  self.args = args
78
78
  self.exception = args[:exception]
@@ -96,7 +96,6 @@ module Honeybadger
96
96
 
97
97
  self.environment_name = args[:environment_name]
98
98
  self.cgi_data = args[:cgi_data] || args[:rack_env]
99
- self.user = args[:user]
100
99
  self.backtrace = Backtrace.parse(exception_attribute(:backtrace, caller), :filters => self.backtrace_filters)
101
100
  self.error_class = exception_attribute(:error_class) {|exception| exception.class.name }
102
101
  self.error_message = exception_attribute(:error_message, 'Notification') do |exception|
@@ -112,6 +111,7 @@ module Honeybadger
112
111
  find_session_data
113
112
  clean_params
114
113
  clean_rack_request_data
114
+ set_context
115
115
  end
116
116
 
117
117
  # Public: Template used to create JSON payload
@@ -137,7 +137,7 @@ module Honeybadger
137
137
  :params => parameters,
138
138
  :session => session_data,
139
139
  :cgi_data => cgi_data,
140
- :user => user
140
+ :context => context
141
141
  },
142
142
  :server => {
143
143
  :project_root => project_root,
@@ -184,7 +184,7 @@ module Honeybadger
184
184
  :backtrace_filters, :parameters, :params_filters, :environment_filters,
185
185
  :session_data, :project_root, :url, :ignore, :ignore_by_filters,
186
186
  :notifier_name, :notifier_url, :notifier_version, :component, :action,
187
- :cgi_data, :environment_name, :hostname, :user, :source_extract,
187
+ :cgi_data, :environment_name, :hostname, :context, :source_extract,
188
188
  :source_extract_radius
189
189
 
190
190
  # Private: Arguments given in the initializer
@@ -303,6 +303,12 @@ module Honeybadger
303
303
  self.session_data = session_data[:data] if session_data[:data]
304
304
  end
305
305
 
306
+ def set_context
307
+ self.context = Thread.current[:honeybadger_context] || {}
308
+ self.context.merge!(args[:context]) if args[:context]
309
+ self.context = nil if context.empty?
310
+ end
311
+
306
312
  # Private: Converts the mixed class instances and class names into just names
307
313
  # TODO: move this into Configuration or another class
308
314
  def ignored_class_names
@@ -43,6 +43,8 @@ module Honeybadger
43
43
  rescue Exception => raised
44
44
  env['honeybadger.error_id'] = notify_honeybadger(raised,env)
45
45
  raise
46
+ ensure
47
+ Honeybadger.context.clear!
46
48
  end
47
49
 
48
50
  if env['rack.exception']
@@ -7,8 +7,7 @@ module Honeybadger
7
7
  :controller => params[:controller],
8
8
  :action => params[:action],
9
9
  :url => honeybadger_request_url,
10
- :cgi_data => honeybadger_filter_if_filtering(request.env),
11
- :user => honeybadger_user_info }
10
+ :cgi_data => honeybadger_filter_if_filtering(request.env) }
12
11
  end
13
12
 
14
13
  private
@@ -55,17 +54,6 @@ module Honeybadger
55
54
  end
56
55
  end
57
56
 
58
- def honeybadger_user_info
59
- method = Honeybadger.configuration.current_user_method
60
-
61
- if respond_to?(method) && user = send(method)
62
- {
63
- :id => user.id,
64
- :email => user.respond_to?(:email) ? user.email : 'N/A'
65
- }
66
- end
67
- end
68
-
69
57
  def honeybadger_request_url
70
58
  url = "#{request.protocol}#{request.host}"
71
59
 
@@ -14,6 +14,7 @@ module Honeybadger::RakeHandler
14
14
  (Honeybadger.configuration.rescue_rake_exceptions===nil && !self.tty_output?))
15
15
 
16
16
  Honeybadger.notify_or_ignore(ex, :component => reconstruct_command_line, :cgi_data => ENV)
17
+ Honeybadger.context.clear!
17
18
  end
18
19
 
19
20
  display_error_message_without_honeybadger(ex)
data/test/test_helper.rb CHANGED
@@ -27,12 +27,14 @@ end
27
27
  module DefinesConstants
28
28
  def setup
29
29
  @defined_constants = []
30
+ Honeybadger.context.clear!
30
31
  end
31
32
 
32
33
  def teardown
33
34
  @defined_constants.each do |constant|
34
35
  Object.__send__(:remove_const, constant)
35
36
  end
37
+ Honeybadger.context.clear!
36
38
  end
37
39
 
38
40
  def define_constant(name, value)
@@ -27,10 +27,14 @@ class ConfigurationTest < Honeybadger::UnitTest
27
27
  assert_config_default :ignore,
28
28
  Honeybadger::Configuration::IGNORE_DEFAULT
29
29
  assert_config_default :framework, 'Standalone'
30
- assert_config_default :current_user_method, :current_user
31
30
  assert_config_default :source_extract_radius, 2
32
31
  end
33
32
 
33
+ should "stub current_user_method" do
34
+ config = Honeybadger::Configuration.new
35
+ assert_nothing_raised { config.current_user_method = :foo }
36
+ end
37
+
34
38
  should "provide default values for secure connections" do
35
39
  config = Honeybadger::Configuration.new
36
40
  config.secure = true
@@ -69,7 +73,6 @@ class ConfigurationTest < Honeybadger::UnitTest
69
73
  assert_config_overridable :notifier_url
70
74
  assert_config_overridable :environment_name
71
75
  assert_config_overridable :logger
72
- assert_config_overridable :current_user_method
73
76
  end
74
77
 
75
78
  should "have an api key" do
@@ -169,10 +169,6 @@ class NoticeTest < Honeybadger::UnitTest
169
169
  assert_equal data, notice.cgi_data, "should take CGI data from a hash"
170
170
  end
171
171
 
172
- should "accept user" do
173
- assert_equal 'foo@bar.com', build_notice(:user => 'foo@bar.com').user
174
- end
175
-
176
172
  should "accept notifier information" do
177
173
  params = { :notifier_name => 'a name for a notifier',
178
174
  :notifier_version => '1.0.5',
@@ -234,7 +230,6 @@ class NoticeTest < Honeybadger::UnitTest
234
230
  assert_nil notice.url
235
231
  assert_nil notice.controller
236
232
  assert_nil notice.action
237
- assert_nil notice.user
238
233
 
239
234
  json = notice.to_json
240
235
  payload = JSON.parse(json)
@@ -244,13 +239,6 @@ class NoticeTest < Honeybadger::UnitTest
244
239
  assert_nil payload['request']['user']
245
240
  end
246
241
 
247
- should "send user in request" do
248
- notice = build_notice(:user => 'foo@bar.com')
249
- json = notice.to_json
250
- payload = JSON.parse(json)
251
- assert_equal payload['request']['user'], 'foo@bar.com'
252
- end
253
-
254
242
  %w(url controller action).each do |var|
255
243
  should "send a request if #{var} is present" do
256
244
  notice = build_notice(var.to_sym => 'value')
@@ -260,7 +248,7 @@ class NoticeTest < Honeybadger::UnitTest
260
248
  end
261
249
  end
262
250
 
263
- %w(parameters cgi_data session_data).each do |var|
251
+ %w(parameters cgi_data session_data context).each do |var|
264
252
  should "send a request if #{var} is present" do
265
253
  notice = build_notice(var.to_sym => { 'key' => 'value' })
266
254
  json = notice.to_json
@@ -329,6 +317,23 @@ class NoticeTest < Honeybadger::UnitTest
329
317
  assert_equal params, notice[:request][:params]
330
318
  end
331
319
 
320
+ should "return context on notice[:request][:context]" do
321
+ context = { 'one' => 'two' }
322
+ notice = build_notice(:context => context)
323
+ assert_equal context, notice[:request][:context]
324
+ end
325
+
326
+ should "merge context from args with context from Honeybadger#context" do
327
+ Honeybadger.context({ 'one' => 'two', 'foo' => 'bar' })
328
+ notice = build_notice(:context => { 'three' => 'four', 'foo' => 'baz' })
329
+ assert_equal({ 'one' => 'two', 'three' => 'four', 'foo' => 'baz' }, notice[:request][:context])
330
+ end
331
+
332
+ should "return nil context when context is not set" do
333
+ notice = build_notice
334
+ assert_equal nil, notice[:request][:context]
335
+ end
336
+
332
337
  should "ensure #to_hash is called on objects that support it" do
333
338
  assert_nothing_raised do
334
339
  build_notice(:session => { :object => stub(:to_hash => {}) })
@@ -53,4 +53,16 @@ class RackTest < Honeybadger::UnitTest
53
53
  expect.with(exception, :rack_env => environment)
54
54
  end
55
55
  end
56
+
57
+ should "clear context after app is called" do
58
+ Honeybadger.context( :foo => :bar )
59
+ assert_equal({ :foo => :bar }, Thread.current[:honeybadger_context])
60
+
61
+ app = lambda { |env| ['response', {}, env] }
62
+ stack = Honeybadger::Rack.new(app)
63
+
64
+ response = stack.call({})
65
+
66
+ assert_equal nil, Thread.current[:honeybadger_context]
67
+ end
56
68
  end
@@ -113,7 +113,6 @@ class ActionControllerCatcherTest < Honeybadger::UnitTest
113
113
  klass.local = opts[:local]
114
114
  controller = klass.new
115
115
  controller.stubs(:rescue_action_in_public_without_honeybadger)
116
- controller.stubs(Honeybadger.configuration.current_user_method).returns(opts[:current_user]) if opts[:current_user]
117
116
  opts[:request].query_parameters = opts[:request].query_parameters.merge(opts[:params] || {})
118
117
  opts[:request].session = ActionController::TestSession.new(opts[:session] || {})
119
118
  # Prevents request.fullpath from crashing Rails in tests
@@ -298,27 +297,4 @@ class ActionControllerCatcherTest < Honeybadger::UnitTest
298
297
  assert_received(session, :data) { |expect| expect.at_least_once }
299
298
  assert_caught_and_sent
300
299
  end
301
-
302
- should "call current_user_method if overridden" do
303
- Honeybadger.configuration.current_user_method = :rockstar
304
-
305
- current_user = mock( :id => 1 )
306
- controller = process_action_with_automatic_notification(:current_user => current_user)
307
- assert_received(controller, :rockstar) { |expect| expect.at_least_once }
308
- assert_caught_and_sent
309
- end
310
-
311
- should "include current_user.id in request user data" do
312
- current_user = stub( :id => 1 )
313
- controller = process_action_with_automatic_notification(:current_user => current_user)
314
- assert_equal({ :id => 1, :email => 'N/A' }, controller.honeybadger_request_data[:user])
315
- assert_caught_and_sent
316
- end
317
-
318
- should "include current_user.email in request user data" do
319
- current_user = stub( :id => 1, :email => 'foo@bar.com' )
320
- controller = process_action_with_automatic_notification(:current_user => current_user)
321
- assert_equal({ :id => 1, :email => 'foo@bar.com' }, controller.honeybadger_request_data[:user])
322
- assert_caught_and_sent
323
- end
324
300
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeybadger
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.1
4
+ version: 1.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-29 00:00:00.000000000 Z
12
+ date: 2012-10-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json