raygun4ruby 1.2.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 80ada759d3d4ae7ad92f5228c4d802fe43f77280
4
- data.tar.gz: eda49a02950403ce1d8db66a379848deb9de014b
3
+ metadata.gz: 177fe25eed9a04d4924bf9a49ce89e521cdc3af3
4
+ data.tar.gz: 4b1ee81e75e37b688a24bb9bc18a8ac187eb2e90
5
5
  SHA512:
6
- metadata.gz: 8f39b4a45ec2e353cd1520f5dd688a40b7e39fbce62fac93c23b88a96cd8d7ee811c5f596bf0dd78ff31e61be3fc3e2920ca8d24ea7450b290da2d10c9045be7
7
- data.tar.gz: 83576e29d1e5156219fadfa97924fcedb49543a6597ef79f9532c188a0cf45e4653cee43ed9417d9cdfd4c784dffcfdb5f2d7a6261e220b2b33c2c024ca58f26
6
+ metadata.gz: 240b3595f0525d734fd067e33db5f21a0f20e3c47901c44c019fb046d35c4566fe685e48343721049507afc711fc30364aa11bffb1d218526a1d28391db06f14
7
+ data.tar.gz: c9054cb36202bab19b695cc08de7c8e48cff4c50cd1e5fa911f9aac217076a0e08cf6984bb2429ffe79d0f0c8c9d6f1e486daf9b4b80de02dea4ae2d767acb09
@@ -1,3 +1,12 @@
1
+ ## 1.3.0 (10/03/2017)
2
+
3
+ Features:
4
+ - Improve affected user handling to let you specify all Raygun parameters, identifier, email, first name, full name and uuid. See [README.md](https://github.com/MindscapeHQ/raygun4ruby#affected-user-tracking) for details
5
+ - Pass a user object as the third parameter to `Raygun.track_exception` to have affected user tracking for manually tracked exceptions, see the above link for more information on configuring this
6
+ - If the exception instance responds to `:raygun_custom_data` that method will be called and the return value merged into the `custom_data` hash sent to Raygun. For convenience a `Raygun::Error` class is provided that takes this custom data as a second argument
7
+ - Allowed `Configuration.custom_data` to be set to a proc to allow a global custom data hook for all exceptions. It is passed as arguments the exception and the environment hash
8
+ - Added `Configuration.debug` to enable logging the reason why an exception was not reported
9
+
1
10
  ## 1.2.1 (09/03/2017)
2
11
 
3
12
  Bugfixes:
data/README.md CHANGED
@@ -74,6 +74,13 @@ rescue Exception => e
74
74
  Raygun.track_exception(e)
75
75
  end
76
76
 
77
+ # You may also pass a user object as the third argument to allow affected user tracking, like so
78
+ begin
79
+ # your lovely code here
80
+ rescue Exception => e
81
+ # The second argument is the request environment variables
82
+ Raygun.track_exception(e, {}, user)
83
+ end
77
84
  ```
78
85
 
79
86
  You can also pass a Hash as the second parameter to `track_exception`. It should look like a [Rack Env Hash](http://rack.rubyforge.org/doc/SPEC.html)
@@ -151,6 +158,26 @@ end
151
158
 
152
159
  ```
153
160
 
161
+ Custom data can also be specified globally either by setting `config.custom_data` to a hash
162
+
163
+ ```ruby
164
+ Raygun.setup do |config|
165
+ config.api_key = "YOUR_RAYGUN_API_KEY"
166
+ config.custom_data = {custom_data: 'goes here'}
167
+ end
168
+ ```
169
+
170
+ or to a proc, which gets passed the exception and environment hash
171
+
172
+ ```ruby
173
+ Raygun.setup do |config|
174
+ config.api_key = "YOUR_RAYGUN_API_KEY"
175
+ config.custom_data do |e, env|
176
+ {message: e.message, server: env["SERVER_NAME"]}
177
+ end
178
+ end
179
+ ```
180
+
154
181
  ### Ignoring Some Errors
155
182
 
156
183
  You can ignore certain types of Exception using the `ignore` option in the setup block, like so:
@@ -199,21 +226,30 @@ end
199
226
 
200
227
  Raygun can now track how many users have been affected by an error.
201
228
 
202
- By default, Raygun looks for a method called `current_user` on your controller, and calls either `email`, `username` or `id` on the object returned by that method.
229
+ By default, Raygun looks for a method called `current_user` on your controller, and it will populate the user's information based on a default method name mapping.
203
230
 
204
- You can customize those method names in your configuration block:
231
+ (e.g Raygun will call `email` to populate the user's email, and `first_name` for the user's first name)
232
+
233
+ You can inspect and customize this mapping using `config.affected_user_mapping`, like so:
205
234
 
206
235
  ```ruby
207
236
  Raygun.setup do |config|
208
237
  config.api_key = "MY_SWEET_API_KEY"
209
238
  config.affected_user_method = :my_current_user # `current_user` by default
210
- config.affected_user_identifier_methods << :login # `[ :email, :username, :id ]` by default - will use the first that works
239
+ # To augment the defaults with your unique methods you can do the following
240
+ config.affected_user_mapping = Raygun::AffectedUser::DEFAULT_MAPPING.merge({
241
+ identifier: :some_custom_unique_identifier,
242
+ # If you set the key to a proc it will be passed the user object and you can construct the value your self
243
+ full_name: ->(user) { "#{user.first_name} #{user.last_name}" }
244
+ })
211
245
  end
212
246
  ```
213
247
 
248
+ To see the defaults check out [affected_user.rb](https://github.com/MindscapeHQ/raygun4ruby/tree/master/lib/raygun/affected_user.rb)
249
+
214
250
  If you're using Rails, most authentication systems will have this method set and you should be good to go.
215
251
 
216
- The count of unique affected users will appear on the error group in the Raygun dashboard. If your user has an `email` method, and that email has a Gravatars associated, you will also see your user's avatar.
252
+ The count of unique affected users will appear on the error group in the Raygun dashboard. If your user has an `Email` attribute, and that email has a Gravatar associated with that address, you will also see your user's avatar.
217
253
 
218
254
  If you wish to keep it anonymous, you could set this identifier to something like `SecureRandom.uuid` and store that in a cookie, like so:
219
255
 
@@ -5,17 +5,20 @@ require "socket"
5
5
  require "rack"
6
6
  require "ostruct"
7
7
 
8
+ begin
9
+ require "pry"
10
+ rescue LoadError
11
+ end
12
+
8
13
  require "raygun/version"
9
14
  require "raygun/configuration"
10
15
  require "raygun/client"
11
16
  require "raygun/middleware/rack_exception_interceptor"
12
17
  require "raygun/testable"
18
+ require "raygun/error"
19
+ require "raygun/affected_user"
13
20
  require "raygun/services/apply_whitelist_filter_to_payload"
14
21
  require "raygun/railtie" if defined?(Rails)
15
- begin
16
- require "pry"
17
- rescue LoadError
18
- end
19
22
 
20
23
  module Raygun
21
24
 
@@ -46,10 +49,10 @@ module Raygun
46
49
  !!configuration.api_key
47
50
  end
48
51
 
49
- def track_exception(exception_instance, env = {}, retry_count = 1)
52
+ def track_exception(exception_instance, env = {}, user = nil, retry_count = 1)
50
53
  if should_report?(exception_instance)
51
54
  log("[Raygun] Tracking Exception...")
52
- Client.new.track_exception(exception_instance, env)
55
+ Client.new.track_exception(exception_instance, env, user)
53
56
  end
54
57
  rescue Exception => e
55
58
  if configuration.failsafe_logger
@@ -63,7 +66,7 @@ module Raygun
63
66
  env[:custom_data] ||= {}
64
67
  env[:custom_data].merge!(original_stacktrace: exception_instance.backtrace)
65
68
 
66
- track_exception(new_exception, env, retry_count - 1)
69
+ track_exception(new_exception, env, user, retry_count - 1)
67
70
  else
68
71
  raise e
69
72
  end
@@ -83,17 +86,38 @@ module Raygun
83
86
  configuration.failsafe_logger.info(message)
84
87
  end
85
88
 
89
+ def deprecation_warning(message)
90
+ if defined?(ActiveSupport::Deprecation)
91
+ ActiveSupport::Deprecation.warn(message)
92
+ else
93
+ puts message
94
+ end
95
+ end
96
+
86
97
  private
87
98
 
88
- def print_api_key_warning
89
- $stderr.puts(NO_API_KEY_MESSAGE)
99
+ def print_api_key_warning
100
+ $stderr.puts(NO_API_KEY_MESSAGE)
101
+ end
102
+
103
+ def should_report?(exception)
104
+ if configuration.silence_reporting
105
+ if configuration.debug
106
+ log('[Raygun] skipping reporting because Configuration.silence_reporting is enabled')
107
+ end
108
+
109
+ return false
90
110
  end
91
111
 
92
- def should_report?(exception)
93
- return false if configuration.silence_reporting
94
- return false if configuration.ignore.flatten.include?(exception.class.to_s)
95
- true
112
+ if configuration.ignore.flatten.include?(exception.class.to_s)
113
+ if configuration.debug
114
+ log("[Raygun] skipping reporting of exception #{exception.class} because it is in the ignore list")
115
+ end
116
+
117
+ return false
96
118
  end
97
119
 
120
+ true
121
+ end
98
122
  end
99
123
  end
@@ -0,0 +1,59 @@
1
+ module Raygun
2
+ class AffectedUser
3
+
4
+ DEFAULT_MAPPING = {
5
+ identifier: [ :id, :username ],
6
+ email: :email,
7
+ full_name: [ :full_name, :name ],
8
+ first_name: :first_name,
9
+ uuid: :uuid
10
+ }.freeze
11
+ SUPPORTED_ATTRIBUTES = DEFAULT_MAPPING.keys.freeze
12
+ NAME_TO_RAYGUN_NAME_MAPPING = {
13
+ identifier: :Identifier,
14
+ email: :Email,
15
+ full_name: :FullName,
16
+ first_name: :FirstName,
17
+ uuid: :UUID
18
+ }.freeze
19
+
20
+ class << self
21
+ def information_hash(user_object)
22
+ if user_object.nil? || user_object.is_a?(String)
23
+ handle_anonymous_user(user_object)
24
+ else
25
+ handle_known_user(user_object)
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def handle_anonymous_user(user_object)
32
+ result = { IsAnonymous: true }
33
+ result[:Identifier] = user_object unless user_object.nil?
34
+ result
35
+ end
36
+
37
+ def handle_known_user(user_object)
38
+ SUPPORTED_ATTRIBUTES.reduce({ IsAnonymous: false }) do |result, attribute|
39
+ mapping = Raygun.configuration.affected_user_mapping
40
+ method = mapping[attribute]
41
+
42
+ value = if method.is_a? Proc
43
+ method.call(user_object)
44
+ else
45
+ attributes = Array(method)
46
+ attribute_to_use = attributes.select do |attr|
47
+ user_object.respond_to?(attr, true)
48
+ end.first
49
+
50
+ user_object.send(attribute_to_use) unless attribute_to_use == nil
51
+ end
52
+
53
+ result[NAME_TO_RAYGUN_NAME_MAPPING[attribute]] = value unless value == nil
54
+ result
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -23,8 +23,8 @@ module Raygun
23
23
  Raygun.configuration.api_key || print_api_key_warning
24
24
  end
25
25
 
26
- def track_exception(exception_instance, env = {})
27
- create_entry(build_payload_hash(exception_instance, env))
26
+ def track_exception(exception_instance, env = {}, user = nil)
27
+ create_entry(build_payload_hash(exception_instance, env, user))
28
28
  end
29
29
 
30
30
  private
@@ -141,8 +141,14 @@ module Raygun
141
141
  end
142
142
 
143
143
  # see http://raygun.io/raygun-providers/rest-json-api?v=1
144
- def build_payload_hash(exception_instance, env = {})
144
+ def build_payload_hash(exception_instance, env = {}, user = nil)
145
145
  custom_data = filter_custom_data(env) || {}
146
+ exception_custom_data = if exception_instance.respond_to?(:raygun_custom_data)
147
+ exception_instance.raygun_custom_data
148
+ else
149
+ {}
150
+ end
151
+
146
152
  tags = env.delete(:tags) || []
147
153
 
148
154
  if rails_env
@@ -153,19 +159,31 @@ module Raygun
153
159
 
154
160
  grouping_key = env.delete(:grouping_key)
155
161
 
162
+ configuration_custom_data = Raygun.configuration.custom_data
163
+ configured_custom_data = if configuration_custom_data.is_a?(Proc)
164
+ configuration_custom_data.call(exception_instance, env)
165
+ else
166
+ configuration_custom_data
167
+ end
168
+
156
169
  error_details = {
157
170
  machineName: hostname,
158
171
  version: version,
159
172
  client: client_details,
160
173
  error: error_details(exception_instance),
161
- userCustomData: Raygun.configuration.custom_data.merge(custom_data),
174
+ userCustomData: exception_custom_data.merge(custom_data).merge(configured_custom_data),
162
175
  tags: Raygun.configuration.tags.concat(tags).compact.uniq,
163
176
  request: request_information(env)
164
177
  }
165
178
 
166
179
  error_details.merge!(groupingKey: grouping_key) if grouping_key
167
180
 
168
- error_details.merge!(user: user_information(env)) if affected_user_present?(env)
181
+ user_details = if affected_user_present?(env)
182
+ user_information(env)
183
+ elsif user != nil
184
+ AffectedUser.information_hash(user)
185
+ end
186
+ error_details.merge!(user: user_details) unless user_details == nil
169
187
 
170
188
  if Raygun.configuration.filter_payload_with_whitelist
171
189
  error_details = filter_payload_with_whitelist(error_details)
@@ -11,6 +11,17 @@ module Raygun
11
11
  end
12
12
  end
13
13
 
14
+ def self.proc_config_option(name)
15
+ define_method(name) do |&block|
16
+ set_value(name, block) unless block == nil
17
+ read_value(name)
18
+ end
19
+
20
+ define_method("#{name}=") do |value|
21
+ set_value(name, value)
22
+ end
23
+ end
24
+
14
25
  # Your Raygun API Key - this can be found on your dashboard at Raygun.io
15
26
  config_option :api_key
16
27
 
@@ -21,7 +32,7 @@ module Raygun
21
32
  config_option :version
22
33
 
23
34
  # Custom Data to send with each exception
24
- config_option :custom_data
35
+ proc_config_option :custom_data
25
36
 
26
37
  # Tags to send with each exception
27
38
  config_option :tags
@@ -38,21 +49,24 @@ module Raygun
38
49
  # Which controller method should we call to find out the affected user?
39
50
  config_option :affected_user_method
40
51
 
41
- # Which methods should we try on the affected user object in order to get an identifier
42
- config_option :affected_user_identifier_methods
52
+ # Mapping of methods for the affected user object - which methods should we call for user information
53
+ config_option :affected_user_mapping
43
54
 
44
55
  # Which parameter keys should we filter out by default?
45
- config_option :filter_parameters
56
+ proc_config_option :filter_parameters
46
57
 
47
58
  # Should we switch to a white listing mode for keys instead of the default blacklist?
48
59
  config_option :filter_payload_with_whitelist
49
60
 
50
61
  # If :filter_payload_with_whitelist is true, which keys should we whitelist?
51
- config_option :whitelist_payload_shape
62
+ proc_config_option :whitelist_payload_shape
52
63
 
53
64
  # Hash of proxy settings - :address, :port (defaults to 80), :username and :password (both default to nil)
54
65
  config_option :proxy_settings
55
66
 
67
+ # Set this to true to have raygun4ruby log the reason why it skips reporting an exception
68
+ config_option :debug
69
+
56
70
  # Exception classes to ignore by default
57
71
  IGNORE_DEFAULT = ['ActiveRecord::RecordNotFound',
58
72
  'ActionController::RoutingError',
@@ -96,11 +110,12 @@ module Raygun
96
110
  tags: [],
97
111
  enable_reporting: true,
98
112
  affected_user_method: :current_user,
99
- affected_user_identifier_methods: [ :email, :username, :id ],
113
+ affected_user_mapping: AffectedUser::DEFAULT_MAPPING,
100
114
  filter_parameters: DEFAULT_FILTER_PARAMETERS,
101
115
  filter_payload_with_whitelist: false,
102
116
  whitelist_payload_shape: DEFAULT_WHITELIST_PAYLOAD_SHAPE,
103
- proxy_settings: {}
117
+ proxy_settings: {},
118
+ debug: false
104
119
  })
105
120
  end
106
121
 
@@ -120,14 +135,9 @@ module Raygun
120
135
  self.enable_reporting = !value
121
136
  end
122
137
 
123
- def filter_parameters(&filter_proc)
124
- set_value(:filter_parameters, filter_proc) if block_given?
125
- read_value(:filter_parameters)
126
- end
127
-
128
- def whitelist_payload_shape(&filter_proc)
129
- set_value(:whitelist_payload_shape, filter_proc) if block_given?
130
- read_value(:whitelist_payload_shape)
138
+ def affected_user_identifier_methods
139
+ Raygun.deprecation_warning("Please note: You should now user config.affected_user_method_mapping.Identifier instead of config.affected_user_identifier_methods")
140
+ read_value(:affected_user_method_mapping).Identifier
131
141
  end
132
142
 
133
143
  private
@@ -0,0 +1,10 @@
1
+ module Raygun
2
+ class Error < StandardError
3
+ attr_reader :raygun_custom_data
4
+
5
+ def initialize(message, raygun_custom_data = {})
6
+ super(message)
7
+ @raygun_custom_data = raygun_custom_data
8
+ end
9
+ end
10
+ end
@@ -8,24 +8,19 @@ module Raygun
8
8
  end
9
9
 
10
10
  def call(env)
11
- response = @app.call(env)
11
+ @app.call(env)
12
12
  rescue Exception => exception
13
- if (controller = env["action_controller.instance"]) && controller.respond_to?(Raygun.configuration.affected_user_method, true)
14
- user = controller.send(Raygun.configuration.affected_user_method)
13
+ controller = env["action_controller.instance"]
14
+ affected_user_method = Raygun.configuration.affected_user_method
15
15
 
16
- if user
17
- identifier = if (m = Raygun.configuration.affected_user_identifier_methods.detect { |m| user.respond_to?(m) })
18
- user.send(m)
19
- else
20
- user
21
- end
16
+ if controller && controller.respond_to?(affected_user_method, true)
17
+ user = controller.send(affected_user_method)
22
18
 
23
- env["raygun.affected_user"] = { :identifier => identifier }
24
- end
19
+ env["raygun.affected_user"] = Raygun::AffectedUser.information_hash(user)
25
20
  end
21
+
26
22
  raise exception
27
23
  end
28
-
29
24
  end
30
25
  end
31
26
  end
@@ -1,3 +1,3 @@
1
1
  module Raygun
2
- VERSION = "1.2.1"
2
+ VERSION = "1.3.0"
3
3
  end