honeybadger 1.2.1 → 1.3.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.
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