sentry-raven 0.15.6 → 1.0.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: 1fff666c279a1df213e55db40a43a92d1d56e191
4
- data.tar.gz: 6a14c52214fb0bcd5d17cd1cc34b97da444e8a39
3
+ metadata.gz: f6c29eda4efffb38e92186b8494c5fb0fb07ac72
4
+ data.tar.gz: ffbb210ae9749c1a97a27ac15ff1770ef360b561
5
5
  SHA512:
6
- metadata.gz: ff2ac5a67aa7ce889707f05080aae60b6cceda1e2d16d4371b5da717727f91c542408887b83eadc9d41aff9746d336de7d640ba9d0d4caa5997f918d0467bd84
7
- data.tar.gz: 405cf1e14b2b10e0a7c2fbc7ec114532e5de28fd0a95a16d69d64694f80517ca3bef012624c554f0b100aebd69263f3b819714195341b3a553ad7f98d1dc3a72
6
+ metadata.gz: 1e0ed89962c85c679bff0339d347d4b8f0ea17bb7ecef9b1de75693b5775783bbe5c5751c2f4113571efa05161d4f082b827bce8f0b8b7b3a7d731925fcab4b6
7
+ data.tar.gz: efbb4e689d8eed60136e7caffb3070e1fc001f371bdc23eeb576e8fe437327173e3eea99a172891954d56fb35d4c2aecc24d6bece917be8ca93d9802e9efdfdd
data/README.md CHANGED
@@ -7,14 +7,20 @@ A client and integration layer for the [Sentry](https://github.com/getsentry/sen
7
7
 
8
8
  ## Requirements
9
9
 
10
- We test on Ruby MRI 1.8.7/REE through Ruby 2.3 at the latest patchlevel/teeny version. JRuby support is experimental - check TravisCI to see if the build is passing or failing.
10
+ We test on Ruby 1.9, 2.2 and 2.3 at the latest patchlevel/teeny version. Our Rails integration works with Rails 4.2+. JRuby support is experimental - check TravisCI to see if the build is passing or failing.
11
11
 
12
12
  ## Getting Started
13
+
13
14
  ### Install
15
+
14
16
  ```ruby
15
- gem "sentry-raven" #, :github => "getsentry/raven-ruby"
17
+ gem "sentry-raven"
16
18
  ```
17
- ### Set SENTRY_DSN
19
+
20
+ ### Raven only runs when SENTRY_DSN is set
21
+
22
+ Raven will capture and send exceptions to the Sentry server whenever its DSN is set. This makes environment-based configuration easy - if you don't want to send errors in a certain environment, just don't set the DSN in that environment!
23
+
18
24
  ```bash
19
25
  # Set your SENTRY_DSN environment variable.
20
26
  export SENTRY_DSN=http://public:secret@example.com/project-id
@@ -25,10 +31,19 @@ Raven.configure do |config|
25
31
  config.dsn = 'http://public:secret@example.com/project-id'
26
32
  end
27
33
  ```
34
+
35
+ ### Raven doesn't report some kinds of data by default.
36
+
37
+ Raven ignores some exceptions by default - most of these are related to 404s or controller actions not being found. [For a complete list, see the `IGNORE_DEFAULT` constant](https://github.com/getsentry/raven-ruby/blob/master/lib/raven/configuration.rb).
38
+
39
+ Raven doesn't report POST data or cookies by default. In addition, it will attempt to remove any obviously sensitive data, such as credit card or Social Security numbers. For more information about how Sentry processes your data, [check out the documentation on the `processors` config setting.](https://docs.getsentry.com/hosted/clients/ruby/config/)
40
+
28
41
  ### Call
42
+
29
43
  If you use Rails, you're already done - no more configuration required! Check [Integrations](https://docs.getsentry.com/hosted/clients/ruby/integrations/) for more details on other gems Sentry integrates with automatically.
30
44
 
31
45
  Otherwise, Raven supports two methods of capturing exceptions:
46
+
32
47
  ```ruby
33
48
  Raven.capture do
34
49
  # capture any exceptions which happen during execution of this block
@@ -12,8 +12,6 @@ module Raven
12
12
  # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
13
13
  JAVA_INPUT_FORMAT = %r{^(.+)\.([^\.]+)\(([^\:]+)\:(\d+)\)$}
14
14
 
15
- APP_DIRS_PATTERN = /(bin|exe|app|config|lib|test)/
16
-
17
15
  # The file portion of the line (such as app/models/user.rb)
18
16
  attr_reader :file
19
17
 
@@ -49,20 +47,13 @@ module Raven
49
47
  end
50
48
 
51
49
  def in_app
52
- app_dirs = Raven.configuration.app_dirs_pattern || APP_DIRS_PATTERN
53
- @in_app_pattern ||= Regexp.new("^(#{project_root}/)?#{app_dirs}")
54
-
55
- if self.file =~ @in_app_pattern
50
+ if self.file =~ self.class.in_app_pattern
56
51
  true
57
52
  else
58
53
  false
59
54
  end
60
55
  end
61
56
 
62
- def project_root
63
- @project_root ||= Raven.configuration.project_root && Raven.configuration.project_root.to_s
64
- end
65
-
66
57
  # Reconstructs the line in a readable fashion
67
58
  def to_s
68
59
  "#{file}:#{number}:in `#{method}'"
@@ -76,11 +67,20 @@ module Raven
76
67
  "<Line:#{self}>"
77
68
  end
78
69
 
70
+ def self.in_app_pattern
71
+ @in_app_pattern ||= begin
72
+ project_root = Raven.configuration.project_root && Raven.configuration.project_root.to_s
73
+ Regexp.new("^(#{project_root}/)?#{Raven.configuration.app_dirs_pattern || APP_DIRS_PATTERN}")
74
+ end
75
+ end
76
+
79
77
  private
80
78
 
81
79
  attr_writer :file, :number, :method, :module_name
82
80
  end
83
81
 
82
+ APP_DIRS_PATTERN = /(bin|exe|app|config|lib|test)/
83
+
84
84
  # holder for an Array of Backtrace::Line instances
85
85
  attr_reader :lines
86
86
 
@@ -1,5 +1,11 @@
1
1
  require 'raven/version'
2
2
  require 'raven/backtrace'
3
+ require 'raven/processor'
4
+ require 'raven/processor/sanitizedata'
5
+ require 'raven/processor/removecircularreferences'
6
+ require 'raven/processor/utf8conversion'
7
+ require 'raven/processor/cookies'
8
+ require 'raven/processor/post_data'
3
9
  require 'raven/configuration'
4
10
  require 'raven/context'
5
11
  require 'raven/client'
@@ -10,15 +16,7 @@ require 'raven/interfaces/exception'
10
16
  require 'raven/interfaces/single_exception'
11
17
  require 'raven/interfaces/stack_trace'
12
18
  require 'raven/interfaces/http'
13
- require 'raven/processor'
14
- require 'raven/processor/sanitizedata'
15
- require 'raven/processor/removecircularreferences'
16
- require 'raven/processor/utf8conversion'
17
-
18
- major, minor, patch = RUBY_VERSION.split('.').map(&:to_i)
19
- if (major == 1 && minor < 9) || (major == 1 && minor == 9 && patch < 2)
20
- require 'raven/backports/uri'
21
- end
19
+ require 'raven/utils/deep_merge'
22
20
 
23
21
  module Raven
24
22
  AVAILABLE_INTEGRATIONS = %w[delayed_job railties sidekiq rack rake].freeze
@@ -5,7 +5,6 @@ require 'base64'
5
5
  require 'raven/version'
6
6
  require 'raven/okjson'
7
7
  require 'raven/transports/http'
8
- require 'raven/transports/udp'
9
8
 
10
9
  module Raven
11
10
  # Encodes events and sends them to the Sentry server.
@@ -28,8 +27,8 @@ module Raven
28
27
  # Convert to hash
29
28
  event = event.to_hash
30
29
 
31
- if !@state.should_try?
32
- Raven.logger.error("Not sending event due to previous failure(s): #{get_log_message(event)}")
30
+ unless @state.should_try?
31
+ failed_send(nil, event)
33
32
  return
34
33
  end
35
34
 
@@ -40,21 +39,18 @@ module Raven
40
39
  begin
41
40
  transport.send_event(generate_auth_header, encoded_data,
42
41
  :content_type => content_type)
42
+ successful_send
43
43
  rescue => e
44
44
  failed_send(e, event)
45
45
  return
46
46
  end
47
47
 
48
- successful_send
49
-
50
48
  event
51
49
  end
52
50
 
53
51
  def transport
54
52
  @transport ||=
55
53
  case configuration.scheme
56
- when 'udp'
57
- Transports::UDP.new(configuration)
58
54
  when 'http', 'https'
59
55
  Transports::HTTP.new(configuration)
60
56
  when 'dummy'
@@ -81,7 +77,7 @@ module Raven
81
77
 
82
78
  case configuration.encoding
83
79
  when 'gzip'
84
- ['application/octet-stream', strict_encode64(Zlib::Deflate.deflate(encoded))]
80
+ ['application/octet-stream', Base64.strict_encode64(Zlib::Deflate.deflate(encoded))]
85
81
  else
86
82
  ['application/json', encoded]
87
83
  end
@@ -103,23 +99,20 @@ module Raven
103
99
  'Sentry ' + fields.map { |key, value| "#{key}=#{value}" }.join(', ')
104
100
  end
105
101
 
106
- def strict_encode64(string)
107
- if Base64.respond_to? :strict_encode64
108
- Base64.strict_encode64 string
109
- else # Ruby 1.8
110
- Base64.encode64(string)[0..-2]
111
- end
112
- end
113
-
114
102
  def successful_send
115
103
  @state.success
116
104
  end
117
105
 
118
106
  def failed_send(e, event)
119
107
  @state.failure
120
- Raven.logger.error "Unable to record event with remote Sentry server (#{e.class} - #{e.message})"
121
- e.backtrace[0..10].each { |line| Raven.logger.error(line) }
108
+ if e # exception was raised
109
+ Raven.logger.error "Unable to record event with remote Sentry server (#{e.class} - #{e.message})"
110
+ e.backtrace[0..10].each { |line| Raven.logger.error(line) }
111
+ else
112
+ Raven.logger.error "Not sending event due to previous failure(s)."
113
+ end
122
114
  Raven.logger.error("Failed to submit event: #{get_log_message(event)}")
115
+ configuration.transport_failure_callback.call(event) if configuration.transport_failure_callback
123
116
  end
124
117
  end
125
118
 
@@ -84,13 +84,20 @@ module Raven
84
84
  # Optional Proc to be used to send events asynchronously.
85
85
  attr_reader :async
86
86
 
87
+ # Optional Proc, called when the Sentry server cannot be contacted for any reason
88
+ attr_accessor :transport_failure_callback
89
+
87
90
  # Directories to be recognized as part of your app. e.g. if you
88
91
  # have an `engines` dir at the root of your project, you may want
89
92
  # to set this to something like /(app|config|engines|lib)/
90
93
  attr_accessor :app_dirs_pattern
91
94
 
92
- # Catch exceptions before they're been processed by
93
- # ActionDispatch::ShowExceptions or ActionDispatch::DebugExceptions
95
+ # Rails catches exceptions in the ActionDispatch::ShowExceptions or
96
+ # ActionDispatch::DebugExceptions middlewares, depending on the environment.
97
+ # When `rails_report_rescued_exceptions` is true (it is by default), Raven
98
+ # will report exceptions even when they are rescued by these middlewares.
99
+ attr_accessor :rails_report_rescued_exceptions
100
+ # Deprecated accessor
94
101
  attr_accessor :catch_debugged_exceptions
95
102
 
96
103
  # Provide a configurable callback to determine event capture
@@ -113,13 +120,21 @@ module Raven
113
120
  'Sinatra::NotFound',
114
121
  ].freeze
115
122
 
123
+ DEFAULT_PROCESSORS = [
124
+ Raven::Processor::RemoveCircularReferences,
125
+ Raven::Processor::UTF8Conversion,
126
+ Raven::Processor::SanitizeData,
127
+ Raven::Processor::Cookies,
128
+ Raven::Processor::PostData,
129
+ ].freeze
130
+
116
131
  def initialize
117
132
  self.server = ENV['SENTRY_DSN'] if ENV['SENTRY_DSN']
118
133
  @context_lines = 3
119
134
  self.current_environment = ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'default'
120
135
  self.send_modules = true
121
136
  self.excluded_exceptions = IGNORE_DEFAULT.dup
122
- self.processors = [Raven::Processor::RemoveCircularReferences, Raven::Processor::UTF8Conversion, Raven::Processor::SanitizeData]
137
+ self.processors = DEFAULT_PROCESSORS.dup
123
138
  self.ssl_verification = true
124
139
  self.encoding = 'gzip'
125
140
  self.timeout = 1
@@ -127,12 +142,17 @@ module Raven
127
142
  self.proxy = nil
128
143
  self.tags = {}
129
144
  self.async = false
130
- self.catch_debugged_exceptions = true
145
+ self.rails_report_rescued_exceptions = true
146
+ self.transport_failure_callback = false
131
147
  self.sanitize_fields = []
132
148
  self.sanitize_credit_cards = true
133
149
  self.environments = []
134
150
 
135
151
  self.release = detect_release
152
+
153
+ # Try to resolve the hostname to an FQDN, but fall back to whatever the load name is
154
+ self.server_name = Socket.gethostname
155
+ self.server_name = Socket.gethostbyname(hostname).first rescue server_name
136
156
  end
137
157
 
138
158
  def server=(value)
@@ -171,6 +191,11 @@ module Raven
171
191
 
172
192
  alias async? async
173
193
 
194
+ def transport_failure_callback=(value)
195
+ raise ArgumentError.new("transport_failure_callback must be callable (or false to disable)") unless value == false || value.respond_to?(:call)
196
+ @transport_failure_callback = value
197
+ end
198
+
174
199
  # Allows config options to be read like a hash
175
200
  #
176
201
  # @param [Symbol] option Key for a given attribute
@@ -203,6 +228,18 @@ module Raven
203
228
  detect_release_from_git
204
229
  end
205
230
 
231
+ def project_root=(root_dir)
232
+ @project_root = root_dir
233
+ Backtrace::Line.instance_variable_set(:@in_app_pattern, nil) # blow away cache
234
+ end
235
+
236
+ def catch_debugged_exceptions=(boolean)
237
+ Raven.logger.warn "DEPRECATION WARNING: catch_debugged_exceptions has been \
238
+ renamed to rails_report_rescued_exceptions. catch_debugged_exceptions will \
239
+ be removed in raven-ruby 0.17.0"
240
+ self.rails_report_rescued_exceptions = boolean
241
+ end
242
+
206
243
  private
207
244
 
208
245
  def detect_release_from_heroku
@@ -40,7 +40,7 @@ module Raven
40
40
  @level = :error
41
41
  @logger = ''
42
42
  @culprit = nil
43
- @server_name = @configuration.server_name || resolve_hostname
43
+ @server_name = @configuration.server_name
44
44
  @release = @configuration.release
45
45
  @modules = list_gem_specs if @configuration.send_modules
46
46
  @user = {}
@@ -69,10 +69,118 @@ module Raven
69
69
  @level = LOG_LEVELS[@level.to_s.downcase] if @level.is_a?(String) || @level.is_a?(Symbol)
70
70
  end
71
71
 
72
- def resolve_hostname
73
- # Try to resolve the hostname to an FQDN, but fall back to whatever the load name is
74
- hostname = Socket.gethostname
75
- Socket.gethostbyname(hostname).first rescue hostname
72
+ class << self
73
+ def from_exception(exc, options = {}, &block)
74
+ exception_context = get_exception_context(exc) || {}
75
+ options = Raven::Utils::DeepMergeHash.deep_merge(exception_context, options)
76
+
77
+ configuration = options[:configuration] || Raven.configuration
78
+ if exc.is_a?(Raven::Error)
79
+ # Try to prevent error reporting loops
80
+ Raven.logger.info "Refusing to capture Raven error: #{exc.inspect}"
81
+ return nil
82
+ end
83
+ if configuration[:excluded_exceptions].any? { |x| (x === exc rescue false) || x == exc.class.name }
84
+ Raven.logger.info "User excluded error: #{exc.inspect}"
85
+ return nil
86
+ end
87
+
88
+ new(options) do |evt|
89
+ evt.configuration = configuration
90
+ evt.message = "#{exc.class}: #{exc.message}"
91
+ evt.level = options[:level] || :error
92
+
93
+ add_exception_interface(evt, exc)
94
+
95
+ yield evt if block
96
+ end
97
+ end
98
+
99
+ def from_message(message, options = {})
100
+ configuration = options[:configuration] || Raven.configuration
101
+ new(options) do |evt|
102
+ evt.configuration = configuration
103
+ evt.message = message
104
+ evt.level = options[:level] || :error
105
+ evt.interface :message do |int|
106
+ int.message = message
107
+ end
108
+ if options[:backtrace]
109
+ evt.interface(:stacktrace) do |int|
110
+ stacktrace_interface_from(int, evt, options[:backtrace])
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ private
117
+
118
+ def get_exception_context(exc)
119
+ if exc.instance_variable_defined?(:@__raven_context)
120
+ exc.instance_variable_get(:@__raven_context)
121
+ elsif exc.respond_to?(:raven_context)
122
+ exc.raven_context
123
+ end
124
+ end
125
+
126
+ def add_exception_interface(evt, exc)
127
+ evt.interface(:exception) do |exc_int|
128
+ exceptions = [exc]
129
+ context = Set.new [exc.object_id]
130
+
131
+ while exc.respond_to?(:cause) && exc.cause
132
+ exc = exc.cause
133
+ if context.include?(exc.object_id)
134
+ break
135
+ end
136
+ exceptions << exc
137
+ context.add(exc.object_id)
138
+ end
139
+ exceptions.reverse!
140
+
141
+ exc_int.values = exceptions.map do |e|
142
+ SingleExceptionInterface.new do |int|
143
+ int.type = e.class.to_s
144
+ int.value = e.to_s
145
+ int.module = e.class.to_s.split('::')[0...-1].join('::')
146
+
147
+ int.stacktrace =
148
+ if e.backtrace
149
+ StacktraceInterface.new do |stacktrace|
150
+ stacktrace_interface_from(stacktrace, evt, e.backtrace)
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+
158
+ def stacktrace_interface_from(int, evt, backtrace)
159
+ backtrace = Backtrace.parse(backtrace)
160
+
161
+ int.frames = []
162
+ backtrace.lines.reverse_each do |line|
163
+ frame = StacktraceInterface::Frame.new
164
+ frame.abs_path = line.file if line.file
165
+ frame.function = line.method if line.method
166
+ frame.lineno = line.number
167
+ frame.in_app = line.in_app
168
+ frame.module = line.module_name if line.module_name
169
+
170
+ if evt.configuration[:context_lines] && frame.abs_path
171
+ frame.pre_context, frame.context_line, frame.post_context = \
172
+ evt.get_file_context(frame.abs_path, frame.lineno, evt.configuration[:context_lines])
173
+ end
174
+
175
+ int.frames << frame if frame.filename
176
+ end
177
+
178
+ evt.culprit = evt.get_culprit(int.frames)
179
+ end
180
+
181
+ # Because linecache can go to hell
182
+ def _source_lines(_path, _from, _to)
183
+ end
76
184
  end
77
185
 
78
186
  def list_gem_specs
@@ -121,105 +229,6 @@ module Raven
121
229
  data
122
230
  end
123
231
 
124
- def self.from_exception(exc, options = {}, &block)
125
- notes = (exc.instance_variable_defined?(:@__raven_context) && exc.instance_variable_get(:@__raven_context)) || {}
126
- options = notes.merge(options)
127
-
128
- configuration = options[:configuration] || Raven.configuration
129
- if exc.is_a?(Raven::Error)
130
- # Try to prevent error reporting loops
131
- Raven.logger.info "Refusing to capture Raven error: #{exc.inspect}"
132
- return nil
133
- end
134
- if configuration[:excluded_exceptions].any? { |x| (x === exc rescue false) || x == exc.class.name }
135
- Raven.logger.info "User excluded error: #{exc.inspect}"
136
- return nil
137
- end
138
-
139
- new(options) do |evt|
140
- evt.configuration = configuration
141
- evt.message = "#{exc.class}: #{exc.message}"
142
- evt.level = options[:level] || :error
143
-
144
- add_exception_interface(evt, exc)
145
-
146
- block.call(evt) if block
147
- end
148
- end
149
-
150
- def self.from_message(message, options = {})
151
- configuration = options[:configuration] || Raven.configuration
152
- new(options) do |evt|
153
- evt.configuration = configuration
154
- evt.message = message
155
- evt.level = options[:level] || :error
156
- evt.interface :message do |int|
157
- int.message = message
158
- end
159
- if options[:backtrace]
160
- evt.interface(:stacktrace) do |int|
161
- stacktrace_interface_from(int, evt, options[:backtrace])
162
- end
163
- end
164
- end
165
- end
166
-
167
- def self.add_exception_interface(evt, exc)
168
- evt.interface(:exception) do |exc_int|
169
- exceptions = [exc]
170
- context = Set.new [exc.object_id]
171
- while exc.respond_to?(:cause) && exc.cause
172
- exceptions << exc.cause
173
- exc = exc.cause
174
- # TODO(dcramer): ideally this would log to inform the user
175
- if context.include?(exc.object_id)
176
- break
177
- end
178
- context.add(exc.object_id)
179
- end
180
- exceptions.reverse!
181
-
182
- exc_int.values = exceptions.map do |e|
183
- SingleExceptionInterface.new do |int|
184
- int.type = e.class.to_s
185
- int.value = e.to_s
186
- int.module = e.class.to_s.split('::')[0...-1].join('::')
187
-
188
- int.stacktrace =
189
- if e.backtrace
190
- StacktraceInterface.new do |stacktrace|
191
- stacktrace_interface_from(stacktrace, evt, e.backtrace)
192
- end
193
- end
194
- end
195
- end
196
- end
197
- end
198
-
199
- def self.stacktrace_interface_from(int, evt, backtrace)
200
- backtrace = Backtrace.parse(backtrace)
201
- int.frames = backtrace.lines.reverse.map do |line|
202
- StacktraceInterface::Frame.new.tap do |frame|
203
- frame.abs_path = line.file if line.file
204
- frame.function = line.method if line.method
205
- frame.lineno = line.number
206
- frame.in_app = line.in_app
207
- frame.module = line.module_name if line.module_name
208
-
209
- if evt.configuration[:context_lines] && frame.abs_path
210
- frame.pre_context, frame.context_line, frame.post_context = \
211
- evt.get_file_context(frame.abs_path, frame.lineno, evt.configuration[:context_lines])
212
- end
213
- end
214
- end.select(&:filename)
215
-
216
- evt.culprit = evt.get_culprit(int.frames)
217
- end
218
-
219
- # Because linecache can go to hell
220
- def self._source_lines(_path, _from, _to)
221
- end
222
-
223
232
  def get_file_context(filename, lineno, context)
224
233
  return nil, nil, nil unless Raven::LineCache.is_valid_file(filename)
225
234
  lines = Array.new(2 * context + 1) do |i|
@@ -113,10 +113,9 @@ module Raven
113
113
  end
114
114
 
115
115
  def format_env_for_sentry(env_hash)
116
- trimmed_hash = env_hash.select do |k, _v|
116
+ env_hash.select do |k, _v|
117
117
  %w(REMOTE_ADDR SERVER_NAME SERVER_PORT).include? k.to_s
118
118
  end
119
- Hash[trimmed_hash] # select returns an Array in Ruby 1.8
120
119
  end
121
120
  end
122
121
 
@@ -22,7 +22,7 @@ module Raven
22
22
  end
23
23
 
24
24
  config.after_initialize do
25
- if Raven.configuration.catch_debugged_exceptions
25
+ if Raven.configuration.rails_report_rescued_exceptions
26
26
  require 'raven/integrations/rails/middleware/debug_exceptions_catcher'
27
27
  if defined?(::ActionDispatch::DebugExceptions)
28
28
  exceptions_class = ::ActionDispatch::DebugExceptions
@@ -30,10 +30,10 @@ module Raven
30
30
  exceptions_class = ::ActionDispatch::ShowExceptions
31
31
  end
32
32
  unless exceptions_class.nil?
33
- if RUBY_VERSION.to_f < 2.0
34
- exceptions_class.send(:include, Raven::Rails::Middleware::OldDebugExceptionsCatcher)
35
- else
33
+ if exceptions_class.respond_to?(:prepend, true)
36
34
  exceptions_class.send(:prepend, Raven::Rails::Middleware::DebugExceptionsCatcher)
35
+ else
36
+ exceptions_class.send(:include, Raven::Rails::Middleware::OldDebugExceptionsCatcher)
37
37
  end
38
38
  end
39
39
  end
@@ -0,0 +1,16 @@
1
+ module Raven
2
+ class Processor::Cookies < Processor
3
+ def process(data)
4
+ if data[:request]
5
+ # Remove possibly sensitive cookies
6
+ data[:request][:cookies] = nil if data[:request][:cookies]
7
+
8
+ if data[:request][:headers] && data[:request][:headers]["Cookie"]
9
+ data[:request][:headers]["Cookie"] = nil
10
+ end
11
+ end
12
+
13
+ data
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module Raven
2
+ class Processor::PostData < Processor
3
+ def process(data)
4
+ if data[:request] && data[:request][:method] == "POST"
5
+ data[:request][:data] = nil # Remove possibly sensitive POST data
6
+ end
7
+
8
+ data
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,28 @@
1
+ module Raven
2
+ module Utils
3
+ # ported from ActiveSupport
4
+ module DeepMergeHash
5
+ def self.deep_merge(hash, other_hash, &block)
6
+ deep_merge!(hash, other_hash, &block)
7
+ end
8
+
9
+ def self.deep_merge!(hash, other_hash, &block)
10
+ other_hash.each_pair do |current_key, other_value|
11
+ this_value = hash[current_key]
12
+
13
+ hash[current_key] = if this_value.is_a?(Hash) && other_value.is_a?(Hash)
14
+ this_value.deep_merge(other_value, &block)
15
+ else
16
+ if block_given? && key?(current_key)
17
+ block.call(current_key, this_value, other_value)
18
+ else
19
+ other_value
20
+ end
21
+ end
22
+ end
23
+
24
+ hash
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Raven
3
- VERSION = "0.15.6".freeze
3
+ VERSION = "1.0.0".freeze
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sentry-raven
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.6
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sentry Team
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-22 00:00:00.000000000 Z
11
+ date: 2016-05-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -42,30 +42,30 @@ dependencies:
42
42
  name: rubocop
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 0.36.0
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 0.36.0
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '3.0'
61
+ version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '3.0'
68
+ version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec-rails
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -84,16 +84,16 @@ dependencies:
84
84
  name: mime-types
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: '1.16'
89
+ version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: '1.16'
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rest-client
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -147,7 +147,6 @@ files:
147
147
  - LICENSE
148
148
  - README.md
149
149
  - lib/raven.rb
150
- - lib/raven/backports/uri.rb
151
150
  - lib/raven/backtrace.rb
152
151
  - lib/raven/base.rb
153
152
  - lib/raven/cli.rb
@@ -176,6 +175,8 @@ files:
176
175
  - lib/raven/logger.rb
177
176
  - lib/raven/okjson.rb
178
177
  - lib/raven/processor.rb
178
+ - lib/raven/processor/cookies.rb
179
+ - lib/raven/processor/post_data.rb
179
180
  - lib/raven/processor/removecircularreferences.rb
180
181
  - lib/raven/processor/removestacktrace.rb
181
182
  - lib/raven/processor/sanitizedata.rb
@@ -183,7 +184,7 @@ files:
183
184
  - lib/raven/transports.rb
184
185
  - lib/raven/transports/dummy.rb
185
186
  - lib/raven/transports/http.rb
186
- - lib/raven/transports/udp.rb
187
+ - lib/raven/utils/deep_merge.rb
187
188
  - lib/raven/version.rb
188
189
  - lib/sentry-raven-without-integrations.rb
189
190
  - lib/sentry-raven.rb
@@ -199,7 +200,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
199
200
  requirements:
200
201
  - - ">="
201
202
  - !ruby/object:Gem::Version
202
- version: 1.8.7
203
+ version: 1.9.0
203
204
  required_rubygems_version: !ruby/object:Gem::Requirement
204
205
  requirements:
205
206
  - - ">="
@@ -212,3 +213,4 @@ signing_key:
212
213
  specification_version: 4
213
214
  summary: A gem that provides a client interface for the Sentry error logger
214
215
  test_files: []
216
+ has_rdoc: true
@@ -1,104 +0,0 @@
1
- # :stopdoc:
2
-
3
- # Stolen from ruby core's uri/common.rb, with modifications to support 1.8.x
4
- #
5
- # https://github.com/ruby/ruby/blob/trunk/lib/uri/common.rb
6
- #
7
- #
8
-
9
- module URI
10
- TBLENCWWWCOMP_ = {} # :nodoc:
11
- 256.times do |i|
12
- TBLENCWWWCOMP_[i.chr] = '%%%02X' % i
13
- end
14
- TBLENCWWWCOMP_[' '] = '+'
15
- TBLENCWWWCOMP_.freeze
16
- TBLDECWWWCOMP_ = {} # :nodoc:
17
- 256.times do |i|
18
- h, l = i>>4, i&15
19
- TBLDECWWWCOMP_['%%%X%X' % [h, l]] = i.chr
20
- TBLDECWWWCOMP_['%%%x%X' % [h, l]] = i.chr
21
- TBLDECWWWCOMP_['%%%X%x' % [h, l]] = i.chr
22
- TBLDECWWWCOMP_['%%%x%x' % [h, l]] = i.chr
23
- end
24
- TBLDECWWWCOMP_['+'] = ' '
25
- TBLDECWWWCOMP_.freeze
26
-
27
- # Encode given +s+ to URL-encoded form data.
28
- #
29
- # This method doesn't convert *, -, ., 0-9, A-Z, _, a-z, but does convert SP
30
- # (ASCII space) to + and converts others to %XX.
31
- #
32
- # This is an implementation of
33
- # http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
34
- #
35
- # See URI.decode_www_form_component, URI.encode_www_form
36
- def self.encode_www_form_component(s)
37
- str = s.to_s
38
- if RUBY_VERSION < "1.9" && $KCODE =~ /u/i
39
- str.gsub(/([^ a-zA-Z0-9_.-]+)/) do
40
- '%' + $1.unpack('H2' * Rack::Utils.bytesize($1)).join('%').upcase
41
- end.tr(' ', '+')
42
- else
43
- str.gsub(/[^*\-.0-9A-Z_a-z]/) {|m| TBLENCWWWCOMP_[m]}
44
- end
45
- end
46
-
47
- # Decode given +str+ of URL-encoded form data.
48
- #
49
- # This decodes + to SP.
50
- #
51
- # See URI.encode_www_form_component, URI.decode_www_form
52
- def self.decode_www_form_component(str, enc = nil)
53
- raise ArgumentError, "invalid %-encoding (#{str})" unless /\A(?:%[0-9a-fA-F]{2}|[^%])*\z/ =~ str
54
- str.gsub(/\+|%[0-9a-fA-F]{2}/) {|m| TBLDECWWWCOMP_[m]}
55
- end
56
-
57
- # Generate URL-encoded form data from given +enum+.
58
- #
59
- # This generates application/x-www-form-urlencoded data defined in HTML5
60
- # from given an Enumerable object.
61
- #
62
- # This internally uses URI.encode_www_form_component(str).
63
- #
64
- # This method doesn't convert the encoding of given items, so convert them
65
- # before call this method if you want to send data as other than original
66
- # encoding or mixed encoding data. (Strings which are encoded in an HTML5
67
- # ASCII incompatible encoding are converted to UTF-8.)
68
- #
69
- # This method doesn't handle files. When you send a file, use
70
- # multipart/form-data.
71
- #
72
- # This is an implementation of
73
- # http://www.w3.org/TR/html5/forms.html#url-encoded-form-data
74
- #
75
- # URI.encode_www_form([["q", "ruby"], ["lang", "en"]])
76
- # #=> "q=ruby&lang=en"
77
- # URI.encode_www_form("q" => "ruby", "lang" => "en")
78
- # #=> "q=ruby&lang=en"
79
- # URI.encode_www_form("q" => ["ruby", "perl"], "lang" => "en")
80
- # #=> "q=ruby&q=perl&lang=en"
81
- # URI.encode_www_form([["q", "ruby"], ["q", "perl"], ["lang", "en"]])
82
- # #=> "q=ruby&q=perl&lang=en"
83
- #
84
- # See URI.encode_www_form_component, URI.decode_www_form
85
- def self.encode_www_form(enum)
86
- enum.map do |k,v|
87
- if v.nil?
88
- encode_www_form_component(k)
89
- elsif v.respond_to?(:to_ary)
90
- v.to_ary.map do |w|
91
- str = encode_www_form_component(k)
92
- unless w.nil?
93
- str << '='
94
- str << encode_www_form_component(w)
95
- end
96
- end.join('&')
97
- else
98
- str = encode_www_form_component(k)
99
- str << '='
100
- str << encode_www_form_component(v)
101
- end
102
- end.join('&')
103
- end
104
- end
@@ -1,29 +0,0 @@
1
- require 'socket'
2
-
3
- require 'raven/transports'
4
- require 'raven/error'
5
-
6
- module Raven
7
- module Transports
8
- class UDP < Transport
9
- def send_event(auth_header, data, _options = {})
10
- conn.send "#{auth_header}\n\n#{data}", 0
11
- end
12
-
13
- private
14
-
15
- def conn
16
- @conn ||= begin
17
- sock = UDPSocket.new
18
- sock.connect(self.configuration.host, self.configuration.port)
19
- sock
20
- end
21
- end
22
-
23
- def verify_configuration
24
- super
25
- raise Error.new('No port specified') unless self.configuration.port
26
- end
27
- end
28
- end
29
- end