diff -Nru ruby-sentry-raven-2.5.1/benchmarks/benchmark.rb ruby-sentry-raven-2.6.3/benchmarks/benchmark.rb --- ruby-sentry-raven-2.5.1/benchmarks/benchmark.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/benchmarks/benchmark.rb 2017-08-07 17:22:13.000000000 +0000 @@ -35,14 +35,10 @@ LOGGER = Logger.new(nil) Benchmark.ipsa do |x| - x.config(:time => 5, :warmup => 2) + x.config(:time => 10, :warmup => 2) x.report("simple") { Raven.capture_exception(DIVIDE_BY_ZERO) } x.report("rails") { Raven.capture_exception(RAILS_EXC) } - x.report("lots o logs") do - 100.times { LOGGER.debug(rand(100_000).to_s) } - Raven.capture_exception(DIVIDE_BY_ZERO) - end x.compare! end diff -Nru ruby-sentry-raven-2.5.1/changelog.md ruby-sentry-raven-2.6.3/changelog.md --- ruby-sentry-raven-2.5.1/changelog.md 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/changelog.md 2017-08-07 17:22:13.000000000 +0000 @@ -1,3 +1,50 @@ +2.6.3 +----- + +* BUGFIX: Fixed typo in the Heroku warning [@greysteil, #728] +* BUGFIX: Swallow IOErrors when reading the Rack request body [@nateberkopec] +* BUGFIX: Fix invalid UTF-8/circular references when using async [@nateberkopec, #730] + +2.6.2 +----- + +* BUGFIX: If using the Sidekiq or DelayedJob adapters with ActiveJob, ActiveJob wouldn't re-raise upon capturing an exception. [@nateberkopec, 5b02ad4ff2] + +* KNOWN ISSUE: When using `async`, Rack integration is not thread-safe [#721] +* KNOWN ISSUE: When using `async`, encoding errors may be raised [#725] + +2.6.1 +----- + +* BUGFIX: Fix cases where ActionDispatch::RemoteIP would blow up during event creation [@cmoylan, #722] +* BUGFIX: In ActiveJob, don't report exceptions which can be rescued by rescue_from handlers [@bensheldon, #719] + +2.6.0 +----- + +* FEATURE: raven-ruby now marks itself as the "ruby" logger by default, to match raven-js behavior [@nateberkopec] +* FEATURE: You may now override the default sanitization parameters [#712, @nateberkopec] +* FEATURE: Breadcrumb buffers are now publicly accessible [#686, @nateberkopec] +* FEATURE: We yell at you now if you're using Heroku but don't have runtime-dyno-metadata enabled [#715, @nateberkopec] +* FEATURE: project_root will always be set, regardless of framework [#716, @nateberkopec] + +* BUGFIX: Request body and message limits now match Sentry server defaults [#714, @nateberkopec] +* BUGFIX: Sidekiq context now works as expected [#713, @nateberkopec] +* BUGFIX: Capture exceptions in ActiveJob when not using Sidekiq adapter [#709, #671, @nateberkopec] + +2.5.3 +----- + +* BUGFIX: Deal properly with ASCII_8BIT/BINARY encodings [#689, #696, @nateberkopec] + +2.5.2 +----- + +* BUGFIX: raven test executable should be available [#691, @nateberkopec] +* BUGFIX: Fix stack overflow when calling Backtrace#inspect [#690, @nateberkopec] + +* KNOWN ISSUE: Character encoding errors [#689] + 2.5.1 ----- diff -Nru ruby-sentry-raven-2.5.1/debian/changelog ruby-sentry-raven-2.6.3/debian/changelog --- ruby-sentry-raven-2.5.1/debian/changelog 2017-06-04 15:41:22.000000000 +0000 +++ ruby-sentry-raven-2.6.3/debian/changelog 2017-10-01 21:35:32.000000000 +0000 @@ -1,3 +1,21 @@ +ruby-sentry-raven (2.6.3-1) unstable; urgency=medium + + * Team upload + * New upstream version 2.6.3 + * Bump Standards-Version to 4.1.1 (no changes needed) + * Refresh disable-tests-requiring-rubocop.patch + * Install raven script as example instead of in /usr/bin (Closes: #875794) + + -- Cédric Boutillier Sun, 01 Oct 2017 23:35:32 +0200 + +ruby-sentry-raven (2.5.3-1) unstable; urgency=medium + + * Team upload + * New upstream release. + * Bump Standard-Versions to 4.1.0 + + -- Abhijith PA Sun, 03 Sep 2017 12:47:46 +0530 + ruby-sentry-raven (2.5.1-1) unstable; urgency=medium * Team upload diff -Nru ruby-sentry-raven-2.5.1/debian/control ruby-sentry-raven-2.6.3/debian/control --- ruby-sentry-raven-2.5.1/debian/control 2017-06-04 15:41:22.000000000 +0000 +++ ruby-sentry-raven-2.6.3/debian/control 2017-10-01 21:35:32.000000000 +0000 @@ -14,7 +14,7 @@ ruby-rspec-rails, ruby-timecop, ruby-sidekiq -Standards-Version: 3.9.8 +Standards-Version: 4.1.1 Vcs-Git: https://anonscm.debian.org/git/pkg-ruby-extras/ruby-sentry-raven.git Vcs-Browser: https://anonscm.debian.org/cgit/pkg-ruby-extras/ruby-sentry-raven.git Homepage: https://github.com/getsentry/raven-ruby diff -Nru ruby-sentry-raven-2.5.1/debian/patches/disable-tests-requiring-rubocop.patch ruby-sentry-raven-2.6.3/debian/patches/disable-tests-requiring-rubocop.patch --- ruby-sentry-raven-2.5.1/debian/patches/disable-tests-requiring-rubocop.patch 2017-06-04 15:41:22.000000000 +0000 +++ ruby-sentry-raven-2.6.3/debian/patches/disable-tests-requiring-rubocop.patch 2017-10-01 21:35:32.000000000 +0000 @@ -1,12 +1,13 @@ Description: Disable the tests that require rubocop, which is not yet packaged. Author: Balasankar C -Last-Update: 2016-01-30 +Last-Update: 2017-10-01 + --- This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ --- a/spec/raven/integrations/rake_spec.rb +++ b/spec/raven/integrations/rake_spec.rb @@ -5,7 +5,7 @@ - expect(Raven::CLI.test("dummy://12345:67890@sentry.localdomain:3000/sentry/42")).to be true + expect(Raven::CLI.test("dummy://12345:67890@sentry.localdomain:3000/sentry/42", true)).to be true end - it "should capture exceptions in Rake tasks" do diff -Nru ruby-sentry-raven-2.5.1/debian/ruby-sentry-raven.examples ruby-sentry-raven-2.6.3/debian/ruby-sentry-raven.examples --- ruby-sentry-raven-2.5.1/debian/ruby-sentry-raven.examples 1970-01-01 00:00:00.000000000 +0000 +++ ruby-sentry-raven-2.6.3/debian/ruby-sentry-raven.examples 2017-10-01 21:35:32.000000000 +0000 @@ -0,0 +1 @@ +exe/raven diff -Nru ruby-sentry-raven-2.5.1/debian/rules ruby-sentry-raven-2.6.3/debian/rules --- ruby-sentry-raven-2.5.1/debian/rules 2017-06-04 15:41:22.000000000 +0000 +++ ruby-sentry-raven-2.6.3/debian/rules 2017-10-01 21:35:32.000000000 +0000 @@ -11,6 +11,11 @@ rm -rf usr/share/doc/ruby-sentry-raven/doc/js/jquery.js rm -rf doc/js/navigation.js.gz doc/js/search_index.js.gz doc/js/searcher.js.gz doc/js/searcher.js.gz +override_dh_auto_install: + dh_auto_install + #remove raven script from /usr/bin, installed as an example + $(RM) -r debian/ruby-sentry-raven/usr/bin/ + override_dh_auto_clean: dh_auto_clean rm -rf doc diff -Nru ruby-sentry-raven-2.5.1/docs/config.rst ruby-sentry-raven-2.6.3/docs/config.rst --- ruby-sentry-raven-2.5.1/docs/config.rst 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/docs/config.rst 2017-08-07 17:22:13.000000000 +0000 @@ -39,7 +39,7 @@ class SentryJob < ActiveJob::Base queue_as :default - + # Important! Otherwise, we can get caught in an infinite loop. rescue_from(ActiveJob::DeserializationError) { |e| Rails.logger.error e } @@ -82,13 +82,13 @@ .. code-block:: ruby - config.excluded_exceptions = ['ActionController::RoutingError', 'ActiveRecord::RecordNotFound'] + config.excluded_exceptions += ['ActionController::RoutingError', 'ActiveRecord::RecordNotFound'] - You can find the list of exceptions that are excluded by default in ``Raven::Configuration::IGNORE_DEFAULT``. Remember you'll be overriding those defaults by setting this configuration. + You can find the list of exceptions that are excluded by default in ``Raven::Configuration::IGNORE_DEFAULT``. It is suggested that you append to these defaults rather than overwrite them with ``=``. .. describe:: logger - The name of the logger used by Sentry. Default is an instance of Raven::Logger. + The logger used by Sentry. Default is an instance of Raven::Logger. .. code-block:: ruby @@ -118,6 +118,14 @@ The client scrubs the HTTP "Authorization" header of requests before sending them to Sentry, to prevent sensitive credentials from being sent. You can specify additional HTTP headers to ignore: + You can also provide regex-like strings to the sanitizer: + + .. code-block:: ruby + + config.sanitize_fields = ["my_field", "foo(.*)?bar] + + It's also possible to remove HTTP header values which match a list: + .. code-block:: ruby config.sanitize_http_headers = ["Via", "Referer", "User-Agent", "Server", "From"] diff -Nru ruby-sentry-raven-2.5.1/docs/context.rst ruby-sentry-raven-2.6.3/docs/context.rst --- ruby-sentry-raven-2.5.1/docs/context.rst 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/docs/context.rst 2017-08-07 17:22:13.000000000 +0000 @@ -24,6 +24,7 @@ * ``server_name``: the hostname of the server * ``tags``: a mapping of tags describing this event * ``extra``: a mapping of arbitrary context +* ``user``: a mapping of user context Providing Request Context ------------------------- diff -Nru ruby-sentry-raven-2.5.1/docs/integrations/heroku.rst ruby-sentry-raven-2.6.3/docs/integrations/heroku.rst --- ruby-sentry-raven-2.5.1/docs/integrations/heroku.rst 1970-01-01 00:00:00.000000000 +0000 +++ ruby-sentry-raven-2.6.3/docs/integrations/heroku.rst 2017-08-07 17:22:13.000000000 +0000 @@ -0,0 +1,11 @@ +Heroku +====== + +Installation +------------ + +Enable the ``runtime-dyno-metadata`` Heroku Labs feature in order to enable automated release detection: + +:: + + heroku labs:enable runtime-dyno-metadata -a myapp diff -Nru ruby-sentry-raven-2.5.1/docs/integrations/index.rst ruby-sentry-raven-2.6.3/docs/integrations/index.rst --- ruby-sentry-raven-2.5.1/docs/integrations/index.rst 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/docs/integrations/index.rst 2017-08-07 17:22:13.000000000 +0000 @@ -12,6 +12,7 @@ rails rack puma + heroku The following integrations are available: @@ -30,7 +31,7 @@ To explicitly include integrations: -:: +.. sourcecode:: ruby require 'sentry-raven-without-integrations' Raven.inject_only(:railties, :rack, :rake) @@ -38,7 +39,7 @@ To blacklist integrations: -:: +.. sourcecode:: ruby require 'sentry-raven-without-integrations' Raven.inject_without(:sidekiq, :delayed_job) @@ -46,13 +47,13 @@ If you're using bundler, then in your gemfile: -:: +.. sourcecode:: ruby gem 'sentry-raven', require: 'sentry-raven-without-integrations' And in some sort of initializer: -:: +.. sourcecode:: ruby Raven.inject_without(:sidekiq) diff -Nru ruby-sentry-raven-2.5.1/docs/usage.rst ruby-sentry-raven-2.6.3/docs/usage.rst --- ruby-sentry-raven-2.5.1/docs/usage.rst 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/docs/usage.rst 2017-08-07 17:22:13.000000000 +0000 @@ -158,3 +158,19 @@ 'email' => 'clever-girl' } } + +Many Instances +-------------- + +It is possible to have many different instances and configurations of the Raven +client running at once. See the delegation pattern in ``base.rb`` for more +information about how the ``Raven`` module delegates calls to the "main" instance. + +.. code-block:: ruby + + Raven.capture # capture, sent to the main instance + + # You can create as many instances as you like. Provide a context and config. + instance = Raven::Instance.new(Raven::Context.new, Raven::Configuration.new) + +Currently, all integrations use the "main" instance. diff -Nru ruby-sentry-raven-2.5.1/exe/raven ruby-sentry-raven-2.6.3/exe/raven --- ruby-sentry-raven-2.5.1/exe/raven 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/exe/raven 2017-08-07 17:22:13.000000000 +0000 @@ -12,14 +12,6 @@ opt.separator "" opt.separator "Options" - # opt.on("-e","--environment ENVIRONMENT","which environment you want server run") do |environment| - # options[:environment] = environment - # end - - # opt.on("-d","--daemon","runing on daemon mode?") do - # options[:daemon] = true - # end - opt.on("-h", "--help", "help") do puts parser end diff -Nru ruby-sentry-raven-2.5.1/Gemfile ruby-sentry-raven-2.6.3/Gemfile --- ruby-sentry-raven-2.5.1/Gemfile 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/Gemfile 2017-08-07 17:22:13.000000000 +0000 @@ -2,15 +2,32 @@ gemspec -group :test do - gem "rack" - gem "sidekiq" +if ENV["RAILS_VERSION"] && (ENV["RAILS_VERSION"].to_i == 4) + gem "rails", "< 5" + gem "rspec-rails" +elsif ENV["RAILS_VERSION"] && (ENV["RAILS_VERSION"].to_i == 0) + # no-op. No Rails. +else + gem "rails", "< 6" + gem "rspec-rails" end -group :development do - gem "pry" - gem "pry-coolline" - gem "benchmark-ips" - gem "benchmark-ipsa" - gem "ruby-prof" +if RUBY_VERSION < '2.0' + gem "mime-types", "< 3.0.0" + gem "nokogiri", "~> 1.6.8" + gem "rack", "~> 1.6.8" + gem "sidekiq", "< 3.2" +else + gem "rack" + gem "sidekiq" end +gem "pry" +gem "pry-coolline" +gem "benchmark-ips" +gem "benchmark-ipsa" if RUBY_VERSION > '2.0' +gem "ruby-prof", platform: :mri +gem "rake" +gem "rubocop", "~> 0.41.1" +gem "rspec" +gem "timecop" +gem "test-unit", platform: :mri if RUBY_VERSION > '2.2' diff -Nru ruby-sentry-raven-2.5.1/gemfiles/rails42.gemfile ruby-sentry-raven-2.6.3/gemfiles/rails42.gemfile --- ruby-sentry-raven-2.5.1/gemfiles/rails42.gemfile 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/gemfiles/rails42.gemfile 1970-01-01 00:00:00.000000000 +0000 @@ -1,16 +0,0 @@ -source "http://rubygems.org" - -# TODO: move this back to a stable version when one is released which allows -# JSON >= 2.0 -gem "rails", github: "rails/rails", branch: "4-2-stable" -gem "mime-types", "< 3.0.0" -gem "sidekiq", "3.2.1" - -if RUBY_VERSION.to_f >= 2.0 - gem "json", ">= 2.0.0" -else - gem "json", "< 2.0.0" - gem "nokogiri", "~> 1.6.0" -end - -gemspec :path => "../" diff -Nru ruby-sentry-raven-2.5.1/gemfiles/rails5.gemfile ruby-sentry-raven-2.6.3/gemfiles/rails5.gemfile --- ruby-sentry-raven-2.5.1/gemfiles/rails5.gemfile 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/gemfiles/rails5.gemfile 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -source "http://rubygems.org" - -gem "rails", "~> 5.1.0" -gem "sidekiq" - -gemspec :path => "../" diff -Nru ruby-sentry-raven-2.5.1/lib/raven/backtrace.rb ruby-sentry-raven-2.6.3/lib/raven/backtrace.rb --- ruby-sentry-raven-2.5.1/lib/raven/backtrace.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/lib/raven/backtrace.rb 2017-08-07 17:22:13.000000000 +0000 @@ -110,7 +110,7 @@ end def inspect - "" + "" end def to_s diff -Nru ruby-sentry-raven-2.5.1/lib/raven/breadcrumbs.rb ruby-sentry-raven-2.6.3/lib/raven/breadcrumbs.rb --- ruby-sentry-raven-2.5.1/lib/raven/breadcrumbs.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/lib/raven/breadcrumbs.rb 2017-08-07 17:22:13.000000000 +0000 @@ -28,6 +28,8 @@ class BreadcrumbBuffer include Enumerable + attr_accessor :buffer + def self.current Thread.current[:sentry_breadcrumbs] ||= new end diff -Nru ruby-sentry-raven-2.5.1/lib/raven/cli.rb ruby-sentry-raven-2.6.3/lib/raven/cli.rb --- ruby-sentry-raven-2.5.1/lib/raven/cli.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/lib/raven/cli.rb 2017-08-07 17:22:13.000000000 +0000 @@ -1,57 +1,58 @@ module Raven class CLI - def self.test(dsn = nil, silent = false) # rubocop:disable all - if silent - Raven.configuration.logger = ::Logger.new(nil) - else - logger = ::Logger.new(STDOUT) - logger.level = ::Logger::ERROR - logger.formatter = proc do |_severity, _datetime, _progname, msg| - "-> #{msg}\n" - end + def self.test(dsn = nil, silent = false, config = nil) # rubocop:disable all + config ||= Raven.configuration - Raven.configuration.logger = logger - end + config.logger = if silent + ::Logger.new(nil) + else + logger = ::Logger.new(STDOUT) + logger.formatter = proc do |_severity, _datetime, _progname, msg| + "-> #{msg}\n" + end + logger + end - Raven.configuration.timeout = 5 - Raven.configuration.dsn = dsn if dsn + config.timeout = 5 + config.dsn = dsn if dsn # wipe out env settings to ensure we send the event - unless Raven.configuration.capture_allowed? - env_name = Raven.configuration.environments.pop || 'production' - Raven.logger.debug "Setting environment to #{env_name}" - Raven.configuration.current_environment = env_name + unless config.capture_allowed? + env_name = config.environments.pop || 'production' + config.current_environment = env_name end - Raven.logger.debug "Sending a test event:" - Raven.logger.debug "" + instance = Raven::Instance.new(nil, config) + + instance.logger.debug "Sending a test event:" + instance.logger.debug "" begin 1 / 0 rescue ZeroDivisionError => exception - evt = Raven.capture_exception(exception) + evt = instance.capture_exception(exception) end if evt && !(evt.is_a? Thread) if evt.is_a? Hash - Raven.logger.debug "-> event ID: #{evt[:event_id]}" + instance.logger.debug "-> event ID: #{evt[:event_id]}" else - Raven.logger.debug "-> event ID: #{evt.id}" + instance.logger.debug "-> event ID: #{evt.id}" end elsif evt # async configuration if evt.value.is_a? Hash - Raven.logger.debug "-> event ID: #{evt.value[:event_id]}" + instance.logger.debug "-> event ID: #{evt.value[:event_id]}" else - Raven.logger.debug "-> event ID: #{evt.value.id}" + instance.logger.debug "-> event ID: #{evt.value.id}" end else - Raven.logger.debug "" - Raven.logger.debug "An error occurred while attempting to send the event." + instance.logger.debug "" + instance.logger.debug "An error occurred while attempting to send the event." exit 1 end - Raven.logger.debug "" - Raven.logger.debug "Done!" + instance.logger.debug "" + instance.logger.debug "Done!" true end end diff -Nru ruby-sentry-raven-2.5.1/lib/raven/configuration.rb ruby-sentry-raven-2.6.3/lib/raven/configuration.rb --- ruby-sentry-raven-2.5.1/lib/raven/configuration.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/lib/raven/configuration.rb 2017-08-07 17:22:13.000000000 +0000 @@ -99,6 +99,10 @@ # a hash key, will be censored and not sent to Sentry. attr_accessor :sanitize_fields + # If you're sure you want to override the default sanitization values, you can + # add to them to an array of Strings here, e.g. %w(authorization password) + attr_accessor :sanitize_fields_excluded + # Sanitize additional HTTP headers - only Authorization is removed by default. attr_accessor :sanitize_http_headers @@ -185,12 +189,14 @@ self.logger = ::Raven::Logger.new(STDOUT) self.open_timeout = 1 self.processors = DEFAULT_PROCESSORS.dup + self.project_root = detect_project_root self.proxy = nil self.rails_activesupport_breadcrumbs = false self.rails_report_rescued_exceptions = true self.release = detect_release self.sanitize_credit_cards = true self.sanitize_fields = [] + self.sanitize_fields_excluded = [] self.sanitize_http_headers = [] self.send_modules = true self.server = ENV['SENTRY_DSN'] if ENV['SENTRY_DSN'] @@ -286,28 +292,45 @@ detect_release_from_git || detect_release_from_capistrano || detect_release_from_heroku + rescue => ex + logger.error "Error detecting release: #{ex.message}" + end + + def detect_project_root + if defined? Rails.root # we are in a Rails application + Rails.root.to_s + else + Dir.pwd + end end private def detect_release_from_heroku - sys_dyno_info = File.read("/etc/heroku/dyno").strip if File.directory?("/etc/heroku") rescue nil - return unless sys_dyno_info + return unless running_on_heroku? + logger.warn(heroku_dyno_metadata_message) && return unless ENV['HEROKU_SLUG_COMMIT'] - # being overly cautious, because if we raise an error Raven won't start - begin - hash = JSON.parse(sys_dyno_info) - hash && hash["release"] && hash["release"]["commit"] - rescue JSON::JSONError - logger.error "Cannot parse Heroku JSON: #{sys_dyno_info}" - end + ENV['HEROKU_SLUG_COMMIT'] + end + + def running_on_heroku? + File.directory?("/etc/heroku") + end + + def heroku_dyno_metadata_message + "You are running on Heroku but haven't enabled Dyno Metadata. For Sentry's "\ + "release detection to work correctly, please run `heroku labs:enable runtime-dyno-metadata`" end def detect_release_from_capistrano - version = File.read(File.join(project_root, 'REVISION')).strip rescue nil + revision_file = File.join(project_root, 'REVISION') + revision_log = File.join(project_root, '..', 'revisions.log') - # Capistrano 3.0 - 3.1.x - version || File.open(File.join(project_root, '..', 'revisions.log')).to_a.last.strip.sub(/.*as release ([0-9]+).*/, '\1') rescue nil + if File.exist?(revision_file) + File.read(revision_file).strip + elsif File.exist?(revision_log) + File.open(revision_log).to_a.last.strip.sub(/.*as release ([0-9]+).*/, '\1') + end end def detect_release_from_git diff -Nru ruby-sentry-raven-2.5.1/lib/raven/event.rb ruby-sentry-raven-2.6.3/lib/raven/event.rb --- ruby-sentry-raven-2.5.1/lib/raven/event.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/lib/raven/event.rb 2017-08-07 17:22:13.000000000 +0000 @@ -19,6 +19,9 @@ }.freeze BACKTRACE_RE = /^(.+?):(\d+)(?::in `(.+?)')?$/ + # See Sentry server default limits at + # https://github.com/getsentry/sentry/blob/master/src/sentry/conf/server.py + MAX_MESSAGE_SIZE_IN_BYTES = 1024 * 8 PLATFORM = "ruby".freeze SDK = { "name" => "raven-ruby", "version" => Raven::VERSION }.freeze @@ -38,7 +41,7 @@ @timestamp = Time.now.utc @time_spent = nil @level = :error - @logger = '' + @logger = 'ruby' @culprit = nil @server_name = @configuration.server_name @release = @configuration.release @@ -106,7 +109,7 @@ new(options) do |evt| evt.configuration = configuration - evt.message = "#{exc.class}: #{exc.message}".byteslice(0...10_000) # Messages limited to 10kb + evt.message = "#{exc.class}: #{exc.message}".byteslice(0...MAX_MESSAGE_SIZE_IN_BYTES) # Messages limited to 10kb evt.level = options[:level] || :error add_exception_interface(evt, exc) @@ -116,7 +119,7 @@ end def from_message(message, options = {}) - message = message.byteslice(0...10_000) # Messages limited to 10kb + message = message.byteslice(0...MAX_MESSAGE_SIZE_IN_BYTES) configuration = options[:configuration] || Raven.configuration new(options) do |evt| @@ -276,7 +279,8 @@ end def to_json_compatible - JSON.parse(JSON.generate(to_hash)) + cleaned_hash = async_json_processors.reduce(to_hash) { |a, e| e.process(a) } + JSON.parse(JSON.generate(cleaned_hash)) end # For cross-language compat @@ -299,5 +303,12 @@ :forwarded_for => context.rack_env["HTTP_X_FORWARDED_FOR"] ).calculate_ip end + + def async_json_processors + [ + Raven::Processor::RemoveCircularReferences, + Raven::Processor::UTF8Conversion + ].map { |v| v.new(self) } + end end end diff -Nru ruby-sentry-raven-2.5.1/lib/raven/integrations/rack.rb ruby-sentry-raven-2.6.3/lib/raven/integrations/rack.rb --- ruby-sentry-raven-2.5.1/lib/raven/integrations/rack.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/lib/raven/integrations/rack.rb 2017-08-07 17:22:13.000000000 +0000 @@ -80,34 +80,46 @@ private + # See Sentry server default limits at + # https://github.com/getsentry/sentry/blob/master/src/sentry/conf/server.py def read_data_from(request) if request.form_data? request.POST elsif request.body # JSON requests, etc - data = request.body.read(2048) # Sentry server limit + data = request.body.read(4096 * 4) # Sentry server limit request.body.rewind data end + rescue IOError => ex + ex.message end def format_headers_for_sentry(env_hash) env_hash.each_with_object({}) do |(key, value), memo| - key = key.to_s # rack env can contain symbols - value = value.to_s - next unless key.upcase == key # Non-upper case stuff isn't either - - # Rack adds in an incorrect HTTP_VERSION key, which causes downstream - # to think this is a Version header. Instead, this is mapped to - # env['SERVER_PROTOCOL']. But we don't want to ignore a valid header - # if the request has legitimately sent a Version header themselves. - # See: https://github.com/rack/rack/blob/028438f/lib/rack/handler/cgi.rb#L29 - next if key == 'HTTP_VERSION' && value == env_hash['SERVER_PROTOCOL'] - - next unless key.start_with?('HTTP_') || %w(CONTENT_TYPE CONTENT_LENGTH).include?(key) - # Rack stores headers as HTTP_WHAT_EVER, we need What-Ever - key = key.gsub("HTTP_", "") - key = key.split('_').map(&:capitalize).join('-') - memo[key] = value + begin + key = key.to_s # rack env can contain symbols + value = value.to_s + next unless key.upcase == key # Non-upper case stuff isn't either + + # Rack adds in an incorrect HTTP_VERSION key, which causes downstream + # to think this is a Version header. Instead, this is mapped to + # env['SERVER_PROTOCOL']. But we don't want to ignore a valid header + # if the request has legitimately sent a Version header themselves. + # See: https://github.com/rack/rack/blob/028438f/lib/rack/handler/cgi.rb#L29 + next if key == 'HTTP_VERSION' && value == env_hash['SERVER_PROTOCOL'] + + next unless key.start_with?('HTTP_') || %w(CONTENT_TYPE CONTENT_LENGTH).include?(key) + # Rack stores headers as HTTP_WHAT_EVER, we need What-Ever + key = key.gsub("HTTP_", "") + key = key.split('_').map(&:capitalize).join('-') + memo[key] = value + rescue StandardError => e + # Rails adds objects to the Rack env that can sometimes raise exceptions + # when `to_s` is called. + # See: https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/remote_ip.rb#L134 + Raven.logger.warn("Error raised while formatting headers: #{e.message}") + next + end end end diff -Nru ruby-sentry-raven-2.5.1/lib/raven/integrations/rails/active_job.rb ruby-sentry-raven-2.6.3/lib/raven/integrations/rails/active_job.rb --- ruby-sentry-raven-2.5.1/lib/raven/integrations/rails/active_job.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/lib/raven/integrations/rails/active_job.rb 2017-08-07 17:22:13.000000000 +0000 @@ -1,31 +1,55 @@ module Raven class Rails - module ActiveJob + module ActiveJobExtensions + ALREADY_SUPPORTED_SENTRY_ADAPTERS = %w( + ActiveJob::QueueAdapters::SidekiqAdapter + ActiveJob::QueueAdapters::DelayedJobAdapter + ).freeze + def self.included(base) base.class_eval do - rescue_from(Exception) do |exception| - # Do not capture exceptions when using Sidekiq so we don't capture - # The same exception twice. - unless self.class.queue_adapter.to_s == 'ActiveJob::QueueAdapters::SidekiqAdapter' - active_job_details = { - :active_job => self.class.name, - :arguments => arguments, - :scheduled_at => scheduled_at, - :job_id => job_id, - :locale => locale - } - - # Add provider_job_id details if Rails 5 - if defined?(provider_job_id) - active_job_details[:provider_job_id] = provider_job_id - end - - Raven.capture_exception(exception, :extra => active_job_details) - raise exception - end + around_perform do |job, block| + capture_and_reraise_with_sentry(job, block) end end end + + def capture_and_reraise_with_sentry(job, block) + block.call + rescue Exception => exception # rubocop:disable Lint/RescueException + return if rescue_with_handler(exception) + unless already_supported_by_specific_integration?(job) + Raven.capture_exception(exception, :extra => raven_context(job)) + end + raise exception + ensure + Context.clear! + BreadcrumbBuffer.clear! + end + + def already_supported_by_specific_integration?(job) + ALREADY_SUPPORTED_SENTRY_ADAPTERS.include?(job.class.queue_adapter.to_s) + end + + def raven_context(job) + ctx = { + :active_job => job.class.name, + :arguments => job.arguments, + :scheduled_at => job.scheduled_at, + :job_id => job.job_id, + :locale => job.locale + } + # Add provider_job_id details if Rails 5 + if job.respond_to?(:provider_job_id) + ctx[:provider_job_id] = job.provider_job_id + end + + ctx + end end end end + +class ActiveJob::Base + include Raven::Rails::ActiveJobExtensions +end diff -Nru ruby-sentry-raven-2.5.1/lib/raven/integrations/rails.rb ruby-sentry-raven-2.6.3/lib/raven/integrations/rails.rb --- ruby-sentry-raven-2.5.1/lib/raven/integrations/rails.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/lib/raven/integrations/rails.rb 2017-08-07 17:22:13.000000000 +0000 @@ -37,11 +37,6 @@ end config.after_initialize do - Raven.configure do |config| - config.project_root ||= ::Rails.root - config.release ||= config.detect_release # if project_root has changed, need to re-check - end - if Raven.configuration.rails_activesupport_breadcrumbs require 'raven/breadcrumbs/activesupport' Raven::ActiveSupportBreadcrumbs.inject @@ -63,6 +58,12 @@ end end + initializer 'raven.active_job' do + ActiveSupport.on_load :active_job do + require 'raven/integrations/rails/active_job' + end + end + rake_tasks do require 'raven/integrations/tasks' end diff -Nru ruby-sentry-raven-2.5.1/lib/raven/integrations/sidekiq.rb ruby-sentry-raven-2.6.3/lib/raven/integrations/sidekiq.rb --- ruby-sentry-raven-2.5.1/lib/raven/integrations/sidekiq.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/lib/raven/integrations/sidekiq.rb 2017-08-07 17:22:13.000000000 +0000 @@ -5,7 +5,6 @@ class SidekiqCleanupMiddleware def call(_worker, _job, _queue) yield - ensure Context.clear! BreadcrumbBuffer.clear! end @@ -22,6 +21,8 @@ :extra => { :sidekiq => context }, :culprit => culprit_from_context(context) ) + Context.clear! + BreadcrumbBuffer.clear! end private diff -Nru ruby-sentry-raven-2.5.1/lib/raven/processor/sanitizedata.rb ruby-sentry-raven-2.6.3/lib/raven/processor/sanitizedata.rb --- ruby-sentry-raven-2.5.1/lib/raven/processor/sanitizedata.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/lib/raven/processor/sanitizedata.rb 2017-08-07 17:22:13.000000000 +0000 @@ -5,13 +5,16 @@ class Processor::SanitizeData < Processor DEFAULT_FIELDS = %w(authorization password passwd secret ssn social(.*)?sec).freeze CREDIT_CARD_RE = /^(?:\d[ -]*?){13,16}$/ + QUERY_STRING = ['query_string', :query_string].freeze + JSON_STARTS_WITH = ["[", "{"].freeze - attr_accessor :sanitize_fields, :sanitize_credit_cards + attr_accessor :sanitize_fields, :sanitize_credit_cards, :sanitize_fields_excluded def initialize(client) super self.sanitize_fields = client.configuration.sanitize_fields self.sanitize_credit_cards = client.configuration.sanitize_credit_cards + self.sanitize_fields_excluded = client.configuration.sanitize_fields_excluded end def process(value, key = nil) @@ -28,7 +31,7 @@ process(json).to_json elsif matches_regexes?(key, value) STRING_MASK - elsif key == 'query_string' || key == :query_string + elsif QUERY_STRING.include?(key) sanitize_query_string(value) else value @@ -59,7 +62,10 @@ end def fields_re - @fields_re ||= /#{(DEFAULT_FIELDS | sanitize_fields).map do |f| + return @fields_re if @fields_re + fields = DEFAULT_FIELDS | sanitize_fields + fields -= sanitize_fields_excluded + @fields_re = /#{fields.map do |f| use_boundary?(f) ? "\\b#{f}\\b" : f end.join("|")}/i end @@ -73,7 +79,7 @@ end def parse_json_or_nil(string) - return unless string.start_with?("[", "{") + return unless string.start_with?(*JSON_STARTS_WITH) JSON.parse(string) rescue JSON::ParserError, NoMethodError nil diff -Nru ruby-sentry-raven-2.5.1/lib/raven/processor/utf8conversion.rb ruby-sentry-raven-2.6.3/lib/raven/processor/utf8conversion.rb --- ruby-sentry-raven-2.5.1/lib/raven/processor/utf8conversion.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/lib/raven/processor/utf8conversion.rb 2017-08-07 17:22:13.000000000 +0000 @@ -18,6 +18,13 @@ clean_exc.set_backtrace(value.backtrace) clean_exc when String + # Encoding::BINARY / Encoding::ASCII_8BIT is a special binary encoding. + # valid_encoding? will always return true because it contains all codepoints, + # so instead we check if it only contains actual ASCII codepoints, and if + # not we assume it's actually just UTF8 and scrub accordingly. + if value.encoding == Encoding::BINARY && !value.ascii_only? + value.force_encoding(Encoding::UTF_8) + end return value if value.valid_encoding? remove_invalid_bytes(value) else diff -Nru ruby-sentry-raven-2.5.1/lib/raven/utils/deep_merge.rb ruby-sentry-raven-2.6.3/lib/raven/utils/deep_merge.rb --- ruby-sentry-raven-2.5.1/lib/raven/utils/deep_merge.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/lib/raven/utils/deep_merge.rb 2017-08-07 17:22:13.000000000 +0000 @@ -12,7 +12,7 @@ this_value = hash[current_key] hash[current_key] = if this_value.is_a?(Hash) && other_value.is_a?(Hash) - this_value.deep_merge(other_value, &block) + deep_merge(this_value, other_value, &block) else if block_given? && key?(current_key) block.call(current_key, this_value, other_value) diff -Nru ruby-sentry-raven-2.5.1/lib/raven/version.rb ruby-sentry-raven-2.6.3/lib/raven/version.rb --- ruby-sentry-raven-2.5.1/lib/raven/version.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/lib/raven/version.rb 2017-08-07 17:22:13.000000000 +0000 @@ -1,5 +1,5 @@ # frozen_string_literal: true module Raven # Freezing this constant breaks in 1.9.x - VERSION = "2.5.1" # rubocop:disable Style/MutableConstant + VERSION = "2.6.3" # rubocop:disable Style/MutableConstant end diff -Nru ruby-sentry-raven-2.5.1/README.md ruby-sentry-raven-2.6.3/README.md --- ruby-sentry-raven-2.5.1/README.md 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/README.md 2017-08-07 17:22:13.000000000 +0000 @@ -1,9 +1,17 @@ -# Raven-Ruby +

+ +

+ +# Raven-Ruby, the Ruby Client for Sentry [![Gem Version](https://img.shields.io/gem/v/sentry-raven.svg)](https://rubygems.org/gems/sentry-raven) [![Build Status](https://img.shields.io/travis/getsentry/raven-ruby/master.svg)](https://travis-ci.org/getsentry/raven-ruby) +[![Gem](https://img.shields.io/gem/dt/sentry-raven.svg)](https://rubygems.org/gems/sentry-raven/) + + +[Documentation](https://docs.getsentry.com/hosted/clients/ruby/) | [Bug Tracker](https://github.com/getsentry/raven-ruby/issues) | [Forum](https://forum.sentry.io/) | IRC: irc.freenode.net, #sentry -A client and integration layer for the [Sentry](https://github.com/getsentry/sentry) error reporting API. +The official Ruby-language client and integration layer for the [Sentry](https://github.com/getsentry/sentry) error reporting API. ## Requirements @@ -32,15 +40,15 @@ end ``` -### Raven doesn't report some kinds of data by default. +### Raven doesn't report some kinds of data by default -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). +**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). 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/) -### Call +### Usage -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. +**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. Otherwise, Raven supports two methods of capturing exceptions: @@ -61,29 +69,6 @@ You're all set - but there's a few more settings you may want to know about too! -#### DSN - -While we advise that you set your Sentry DSN through the `SENTRY_DSN` environment -variable, there are two other configuration settings for controlling Raven: - -```ruby -# DSN can be configured as a config setting instead. -# Place in config/initializers or similar. -Raven.configure do |config| - config.dsn = 'your_dsn' -end -``` - -And, while not necessary if using `SENTRY_DSN`, you can also provide an `environments` -setting. Raven will only capture events when `RACK_ENV` or `RAILS_ENV` matches -an environment in the list. - -```ruby -Raven.configure do |config| - config.environments = %w[staging production] -end -``` - #### async When an error or message occurs, the notification is immediately sent to Sentry. Raven can be configured to send asynchronously: @@ -96,15 +81,17 @@ Using a thread to send events will be adequate for truly parallel Ruby platforms such as JRuby, though the benefit on MRI/CRuby will be limited. If the async callback raises an exception, Raven will attempt to send synchronously. -We recommend creating a background job, using your background job processor, that will send Sentry notifications in the background. Rather than enqueuing an entire Raven::Event object, we recommend providing the Hash representation of an event as a job argument. Here’s an example for ActiveJob: +Note that the naive example implementation has a major drawback - it can create an infinite number of threads. We recommend creating a background job, using your background job processor, that will send Sentry notifications in the background. ```ruby -config.async = lambda { |event| - SentryJob.perform_later(event.to_hash) -} +config.async = lambda { |event| SentryJob.perform_later(event) } + class SentryJob < ActiveJob::Base queue_as :default + # Important for ActiveJob! Otherwise, we can get caught in an infinite loop. + rescue_from(ActiveJob::DeserializationError) { |e| Rails.logger.error e } + def perform(event) Raven.send_event(event) end @@ -144,6 +131,5 @@ * [Documentation](https://docs.getsentry.com/hosted/clients/ruby/) * [Bug Tracker](https://github.com/getsentry/raven-ruby/issues) -* [Code](https://github.com/getsentry/raven-ruby) -* [Mailing List](https://groups.google.com/group/getsentry) +* [Forum](https://forum.sentry.io/) * [IRC](irc://irc.freenode.net/sentry>) (irc.freenode.net, #sentry) diff -Nru ruby-sentry-raven-2.5.1/sentry-raven.gemspec ruby-sentry-raven-2.6.3/sentry-raven.gemspec --- ruby-sentry-raven-2.5.1/sentry-raven.gemspec 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/sentry-raven.gemspec 2017-08-07 17:22:13.000000000 +0000 @@ -3,25 +3,20 @@ Gem::Specification.new do |gem| gem.name = "sentry-raven" - gem.version = Raven::VERSION - gem.platform = Gem::Platform::RUBY + gem.authors = ["Sentry Team"] gem.description = gem.summary = "A gem that provides a client interface for the Sentry error logger" gem.email = "getsentry@googlegroups.com" + gem.license = 'Apache-2.0' gem.homepage = "https://github.com/getsentry/raven-ruby" - gem.authors = ["Sentry Team"] + + gem.version = Raven::VERSION + gem.platform = Gem::Platform::RUBY + gem.required_ruby_version = '>= 1.9.0' gem.has_rdoc = true gem.extra_rdoc_files = ["README.md", "LICENSE"] - gem.files = Dir['lib/**/*'] - gem.executables = gem.files.grep(%r{^exe/}) { |f| File.basename(f) } - gem.license = 'Apache-2.0' - gem.required_ruby_version = '>= 1.9.0' + gem.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n") + gem.bindir = "exe" + gem.executables = "raven" gem.add_dependency "faraday", ">= 0.7.6", "< 1.0" - - gem.add_development_dependency "rake" - gem.add_development_dependency "rubocop", "~> 0.41.1" - gem.add_development_dependency "rspec" - gem.add_development_dependency "rspec-rails" - gem.add_development_dependency "timecop" - gem.add_development_dependency "test-unit" if RUBY_VERSION > '2.2' end diff -Nru ruby-sentry-raven-2.5.1/spec/raven/backtrace_spec.rb ruby-sentry-raven-2.6.3/spec/raven/backtrace_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/backtrace_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/backtrace_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe Raven::Backtrace do + before(:each) do + @backtrace = Raven::Backtrace.parse(Thread.current.backtrace) + end + + it "#lines" do + expect(@backtrace.lines.first).to be_a(Raven::Backtrace::Line) + end + + it "#inspect" do + expect(@backtrace.inspect).to match(/Backtrace: .*>$/) + end + + it "#to_s" do + expect(@backtrace.to_s).to match(/backtrace_spec.rb:5/) + end + + it "==" do + @backtrace2 = Raven::Backtrace.new(@backtrace.lines) + expect(@backtrace).to be == @backtrace2 + end +end diff -Nru ruby-sentry-raven-2.5.1/spec/raven/cli_spec.rb ruby-sentry-raven-2.6.3/spec/raven/cli_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/cli_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/cli_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -2,38 +2,34 @@ require 'raven/cli' describe "CLI tests" do - example "posting an exception" do - stubs = Faraday::Adapter::Test::Stubs.new do |stub| - stub.post('sentry/api/42/store/') { [200, {}, 'ok'] } - end - - Raven.configure do |config| + let(:configuration) do + Raven::Configuration.new.tap do |config| config.environments = ["test"] config.current_environment = "test" - config.http_adapter = [:test, stubs] config.silence_ready = true end + end + + it "posting an exception" do + stubs = Faraday::Adapter::Test::Stubs.new do |stub| + stub.post('sentry/api/42/store/') { [200, {}, 'ok'] } + end + configuration.http_adapter = [:test, stubs] dsn = 'http://12345:67890@sentry.localdomain/sentry/42' - Raven::CLI.test(dsn, true) + Raven::CLI.test(dsn, true, configuration) stubs.verify_stubbed_calls end - example "posting an exception to a prefixed DSN" do + it "posting an exception to a prefixed DSN" do stubs = Faraday::Adapter::Test::Stubs.new do |stub| stub.post('/prefix/sentry/api/42/store/') { [200, {}, 'ok'] } end - - Raven.configure do |config| - config.environments = ["test"] - config.current_environment = "test" - config.http_adapter = [:test, stubs] - config.silence_ready = true - end + configuration.http_adapter = [:test, stubs] dsn = 'http://12345:67890@sentry.localdomain/prefix/sentry/42' - Raven::CLI.test(dsn, true) + Raven::CLI.test(dsn, true, configuration) stubs.verify_stubbed_calls end diff -Nru ruby-sentry-raven-2.5.1/spec/raven/event_spec.rb ruby-sentry-raven-2.6.3/spec/raven/event_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/event_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/event_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -179,13 +179,13 @@ let(:hash) do Raven.rack_context('REQUEST_METHOD' => 'GET', 'rack.url_scheme' => 'http', - 'rack.input' => StringIO.new('a' * 16_000)) + 'rack.input' => StringIO.new('a' * 4096 * 5)) Raven::Event.new.to_hash end it "truncates http data" do - expect(hash[:request][:data]).to eq("a" * 2048) + expect(hash[:request][:data]).to eq("a" * 4096 * 4) end end @@ -362,6 +362,33 @@ expect(json["extra"]['date']).to be_a(String) expect(json["extra"]['anonymous_module']).not_to be_a(Class) end + + context "with bad data" do + subject do + data = {} + data['data'] = data + data['ary'] = [] + data['ary'].push('x' => data['ary']) + data['ary2'] = data['ary'] + + Raven::Event.new(:extra => { + :invalid => "invalid\255".force_encoding('UTF-8'), + :circular => data + }) + end + + it "should remove bad UTF-8" do + json = subject.to_json_compatible + + expect(json["extra"]["invalid"]).to eq("invalid") + end + + it "should remove circular references" do + json = subject.to_json_compatible + + expect(json["extra"]["circular"]["ary2"]).to eq("(...)") + end + end end describe '.capture_message' do diff -Nru ruby-sentry-raven-2.5.1/spec/raven/integrations/rack_spec.rb ruby-sentry-raven-2.6.3/spec/raven/integrations/rack_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/integrations/rack_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/integrations/rack_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -2,12 +2,6 @@ require 'raven/integrations/rack' describe Raven::Rack do - before(:all) do - Raven.configure do |config| - config.dsn = 'dummy://12345:67890@sentry.localdomain:3000/sentry/42' - end - end - it 'should capture exceptions' do exception = build_exception env = {} @@ -103,6 +97,19 @@ expect(interface.headers["Version"]).to eq("HTTP/2.0") end + it 'does not fail if an object in the env cannot be cast to string' do + obj = Class.new do + def to_s + raise 'Could not stringify object!' + end + end.new + + env = { "HTTP_FOO" => "BAR", "rails_object" => obj } + interface = Raven::HttpInterface.new + + expect { interface.from_rack(env) }.to_not raise_error + end + it 'should pass rack/lint' do env = Rack::MockRequest.env_for("/test") diff -Nru ruby-sentry-raven-2.5.1/spec/raven/integrations/rails/activejob_spec.rb ruby-sentry-raven-2.6.3/spec/raven/integrations/rails/activejob_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/integrations/rails/activejob_spec.rb 1970-01-01 00:00:00.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/integrations/rails/activejob_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -0,0 +1,83 @@ +require "spec_helper" + +if defined? ActiveJob + class MyActiveJob < ActiveJob::Base + self.queue_adapter = :inline + self.logger = nil + + class TestError < RuntimeError + end + + def perform + raise TestError, "Boom!" + end + end + + class RescuedActiveJob < MyActiveJob + rescue_from TestError, :with => :rescue_callback + + def rescue_callback(error) + end + end +end + +describe "ActiveJob integration", :rails => true do + before(:all) do + require "rspec/rails" + require "raven/integrations/rails" + require "raven/integrations/rails/active_job" + end + + before(:each) do + Raven.client.transport.events = [] + end + + it "captures exceptions" do + job = MyActiveJob.new + + expect { job.perform_now }.to raise_error(MyActiveJob::TestError) + + expect(Raven.client.transport.events.size).to eq(1) + end + + it "clears context" do + Raven.extra_context(:foo => :bar) + job = MyActiveJob.new + + expect { job.perform_now }.to raise_error(MyActiveJob::TestError) + event = JSON.parse!(Raven.client.transport.events.first[1]) + + expect(event["extra"]["foo"]).to eq("bar") + + Raven.client.transport.events = [] + expect { job.perform_now }.to raise_error(MyActiveJob::TestError) + event = JSON.parse!(Raven.client.transport.events.first[1]) + + expect(event["extra"]["foo"]).to eq(nil) + end + + context 'using rescue_from' do + it 'does not trigger Sentry' do + job = RescuedActiveJob.new + allow(job).to receive(:rescue_callback) + + expect { job.perform_now }.not_to raise_error + + expect(Raven.client.transport.events.size).to eq(0) + expect(job).to have_received(:rescue_callback).once + end + end + + context "when we are using an adapter which has a specific integration" do + it "does not trigger sentry and re-raises" do + job = MyActiveJob.new + def job.already_supported_by_specific_integration?(*) + true + end + + expect { job.perform_now }.to raise_error(MyActiveJob::TestError) + + expect(Raven.client.transport.events.size).to eq(0) + end + end +end diff -Nru ruby-sentry-raven-2.5.1/spec/raven/integrations/rails/controller_methods_spec.rb ruby-sentry-raven-2.6.3/spec/raven/integrations/rails/controller_methods_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/integrations/rails/controller_methods_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/integrations/rails/controller_methods_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -1,9 +1,11 @@ require 'spec_helper' -require 'raven' -require 'raven/integrations/rails/controller_methods' -describe Raven::Rails::ControllerMethods do - include described_class +describe "Raven::Rails::ControllerMethods", :rails => true do + include Raven::Rails::ControllerMethods if defined?(Rails) + + before(:all) do + require 'raven/integrations/rails/controller_methods' + end let(:env) { { "foo" => "bar" } } let(:request) { double('request', :env => env) } diff -Nru ruby-sentry-raven-2.5.1/spec/raven/integrations/rails/event_spec.rb ruby-sentry-raven-2.6.3/spec/raven/integrations/rails/event_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/integrations/rails/event_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/integrations/rails/event_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -1,6 +1,6 @@ require 'spec_helper' -describe Raven::Event do +describe Raven::Event, :rails => true do context 'in a rails environment' do before do Raven.configure do |config| diff -Nru ruby-sentry-raven-2.5.1/spec/raven/integrations/rails/overrides/debug_exceptions_catcher_spec.rb ruby-sentry-raven-2.6.3/spec/raven/integrations/rails/overrides/debug_exceptions_catcher_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/integrations/rails/overrides/debug_exceptions_catcher_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/integrations/rails/overrides/debug_exceptions_catcher_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -1,7 +1,10 @@ require 'spec_helper' -require 'raven/integrations/rails/overrides/debug_exceptions_catcher' -describe Raven::Rails::Overrides::DebugExceptionsCatcher do +describe "Raven::Rails::Overrides::DebugExceptionsCatcher", :rails => true do + before(:all) do + require 'raven/integrations/rails/overrides/debug_exceptions_catcher' + end + let(:middleware) do Class.new do def initialize(app) @@ -26,7 +29,7 @@ let(:env) { {} } - if Rails.version < "5.1.0" + if defined?(Rails) && Rails.version < "5.1.0" context "using include" do before do middleware.send(:include, Raven::Rails::Overrides::OldDebugExceptionsCatcher) diff -Nru ruby-sentry-raven-2.5.1/spec/raven/integrations/rails_spec.rb ruby-sentry-raven-2.6.3/spec/raven/integrations/rails_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/integrations/rails_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/integrations/rails_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -1,27 +1,16 @@ require "spec_helper" -require "rspec/rails" -require "raven/transports/dummy" -require "raven/integrations/rack" -require "raven/integrations/rails" -describe TestApp, :type => :request do +describe "Rails Integration", :type => :request, :rails => true do before(:all) do - @original_configuration = Raven.configuration - - Raven.configuration = Raven::Configuration.new.tap do |config| - config.dsn = 'dummy://12345:67890@sentry.localdomain:3000/sentry/42' - config.encoding = 'json' - end + require "rspec/rails" + require "raven/integrations/rack" + require "raven/integrations/rails" Rails.logger = Logger.new(nil) Rails.env = "production" TestApp.initialize! end - after(:all) do - Raven.configuration = @original_configuration - end - after(:each) do Raven.client.transport.events = [] end @@ -50,7 +39,7 @@ end it "sets Raven.configuration.project_root correctly" do - expect(Raven.configuration.project_root).to eq(Rails.root) + expect(Raven.configuration.project_root).to eq(Rails.root.to_s) end it "doesn't clobber a manually configured release" do diff -Nru ruby-sentry-raven-2.5.1/spec/raven/integrations/rake_spec.rb ruby-sentry-raven-2.6.3/spec/raven/integrations/rake_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/integrations/rake_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/integrations/rake_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -2,7 +2,7 @@ describe 'Rake tasks' do it 'should bundle a CLI task which captures exceptions' do - expect(Raven::CLI.test("dummy://12345:67890@sentry.localdomain:3000/sentry/42")).to be true + expect(Raven::CLI.test("dummy://12345:67890@sentry.localdomain:3000/sentry/42", true)).to be true end it "should capture exceptions in Rake tasks" do diff -Nru ruby-sentry-raven-2.5.1/spec/raven/integrations/sidekiq_spec.rb ruby-sentry-raven-2.6.3/spec/raven/integrations/sidekiq_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/integrations/sidekiq_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/integrations/sidekiq_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -1,57 +1,142 @@ -require 'spec_helper' -require 'raven/integrations/sidekiq' +if RUBY_VERSION > '2.0' + require 'spec_helper' -describe Raven::SidekiqErrorHandler do - before(:all) do - Raven.configure do |config| - config.dsn = 'dummy://12345:67890@sentry.localdomain:3000/sentry/42' + require 'raven/integrations/sidekiq' + require 'sidekiq/processor' + + describe "Raven::SidekiqErrorHandler" do + let(:context) do + { + "args" => [true, true], + "class" => "HardWorker", + "created_at" => 1_474_922_824.910579, + "enqueued_at" => 1_474_922_824.910665, + "error_class" => "RuntimeError", + "error_message" => "a wild exception appeared", + "failed_at" => 1_474_922_825.158953, + "jid" => "701ed9cfa51c84a763d56bc4", + "queue" => "default", + "retry" => true, + "retry_count" => 0 + } + end + + it "should capture exceptions based on Sidekiq context" do + exception = build_exception + expected_options = { + :message => exception.message, + :extra => { :sidekiq => context }, + :culprit => "Sidekiq/HardWorker" + } + + expect(Raven).to receive(:capture_exception).with(exception, expected_options) + + Raven::SidekiqErrorHandler.new.call(exception, context) + end + + it "filters out ActiveJob keys" do + exception = build_exception + aj_context = context + aj_context["_aj_globalid"] = "oh noes" + expected_context = aj_context + expected_context.delete("_aj_globalid") + expected_context["_globalid"] = "oh noes" + expected_options = { + :message => exception.message, + :extra => { :sidekiq => expected_context }, + :culprit => "Sidekiq/HardWorker" + } + + expect(Raven).to receive(:capture_exception).with(exception, expected_options) + + Raven::SidekiqErrorHandler.new.call(exception, aj_context) end end - let(:context) do - { - "args" => [true, true], - "class" => "HardWorker", - "created_at" => 1_474_922_824.910579, - "enqueued_at" => 1_474_922_824.910665, - "error_class" => "RuntimeError", - "error_message" => "a wild exception appeared", - "failed_at" => 1_474_922_825.158953, - "jid" => "701ed9cfa51c84a763d56bc4", - "queue" => "default", - "retry" => true, - "retry_count" => 0 - } + class HappyWorker + include Sidekiq::Worker + + def perform + Raven.breadcrumbs.record do |crumb| + crumb.message = "I'm happy!" + end + Raven.tags_context :mood => 'happy' + end + end + + class SadWorker + include Sidekiq::Worker + + def perform + Raven.breadcrumbs.record do |crumb| + crumb.message = "I'm sad!" + end + Raven.tags_context :mood => 'sad' + + raise "I'm sad!" + end end - it "should capture exceptions based on Sidekiq context" do - exception = build_exception - expected_options = { - :message => exception.message, - :extra => { :sidekiq => context }, - :culprit => "Sidekiq/HardWorker" - } + class VerySadWorker + include Sidekiq::Worker - expect(Raven).to receive(:capture_exception).with(exception, expected_options) + def perform + Raven.breadcrumbs.record do |crumb| + crumb.message = "I'm very sad!" + end + Raven.tags_context :mood => 'very sad' - subject.call(exception, context) + raise "I'm very sad!" + end end - it "filters out ActiveJob keys" do - exception = build_exception - aj_context = context - aj_context["_aj_globalid"] = "oh noes" - expected_context = aj_context - expected_context.delete("_aj_globalid") - expected_context["_globalid"] = "oh noes" - expected_options = { - :message => exception.message, - :extra => { :sidekiq => expected_context }, - :culprit => "Sidekiq/HardWorker" - } + describe "Sidekiq full-stack integration" do + before(:all) do + Sidekiq.error_handlers << Raven::SidekiqErrorHandler.new + Sidekiq.server_middleware do |chain| + chain.add Raven::SidekiqCleanupMiddleware + end + Sidekiq.logger = Logger.new(nil) + end + + before do + @mgr = double('manager') + allow(@mgr).to receive(:options).and_return(:queues => ['default']) + @processor = ::Sidekiq::Processor.new(@mgr) + end + + def process_job(klass) + msg = Sidekiq.dump_json("class" => klass) + job = Sidekiq::BasicFetch::UnitOfWork.new('queue:default', msg) + @processor.instance_variable_set(:'@job', job) + + @processor.send(:process, job) + rescue # rubocop:disable Lint/HandleExceptions + # do nothing + end - expect(Raven).to receive(:capture_exception).with(exception, expected_options) + it "actually captures an exception" do + expect { process_job("SadWorker") }.to change { Raven.client.transport.events.size }.by(1) + end - subject.call(exception, aj_context) + it "clears context from other workers and captures its own" do + process_job("HappyWorker") + process_job("SadWorker") + + event = JSON.parse(Raven.client.transport.events.last[1]) + + expect(event["tags"]).to eq("mood" => "sad") + expect(event["breadcrumbs"]["values"][0]["message"]).to eq("I'm sad!") + end + + it "clears context after raising" do + process_job("SadWorker") + process_job("VerySadWorker") + + event = JSON.parse(Raven.client.transport.events.last[1]) + + expect(event["tags"]).to eq("mood" => "very sad") + expect(event["breadcrumbs"]["values"][0]["message"]).to eq("I'm very sad!") + end end end diff -Nru ruby-sentry-raven-2.5.1/spec/raven/integration_spec.rb ruby-sentry-raven-2.6.3/spec/raven/integration_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/integration_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/integration_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -1,83 +1,57 @@ require 'spec_helper' describe "Integration tests" do - example "posting an exception" do - stubs = Faraday::Adapter::Test::Stubs.new do |stub| - stub.post('sentry/api/42/store/') { [200, {}, 'ok'] } - end - io = StringIO.new - - Raven.configure do |config| + before(:each) do + @io = StringIO.new + @logger = Logger.new(@io) + @instance = Raven::Instance.new + @stubs = Faraday::Adapter::Test::Stubs.new + @instance.configuration = Raven::Configuration.new.tap do |config| config.server = 'http://12345:67890@sentry.localdomain/sentry/42' - config.http_adapter = [:test, stubs] - config.logger = Logger.new(io) + config.http_adapter = [:test, @stubs] + config.logger = @logger end + end - Raven.capture_exception(build_exception) + it "posting an exception" do + @stubs.post('sentry/api/42/store/') { [200, {}, 'ok'] } - stubs.verify_stubbed_calls + @instance.capture_exception(build_exception) - expect(io.string).to match(/Sending event [0-9a-f]+ to Sentry$/) + @stubs.verify_stubbed_calls + expect(@io.string).to match(/Sending event [0-9a-f]+ to Sentry$/) end - example "posting an exception to a prefixed DSN" do - stubs = Faraday::Adapter::Test::Stubs.new do |stub| - stub.post('/prefix/sentry/api/42/store/') { [200, {}, 'ok'] } - end - - Raven.configure do |config| - config.server = 'http://12345:67890@sentry.localdomain/prefix/sentry/42' - config.http_adapter = [:test, stubs] - end + it "posting an exception to a prefixed DSN" do + @stubs.post('/prefix/sentry/api/42/store/') { [200, {}, 'ok'] } + @instance.configuration.server = 'http://12345:67890@sentry.localdomain/prefix/sentry/42' - Raven.capture_exception(build_exception) + @instance.capture_exception(build_exception) - stubs.verify_stubbed_calls + @stubs.verify_stubbed_calls end - example "hitting quota limit shouldn't swallow exception" do - stubs = Faraday::Adapter::Test::Stubs.new do |stub| - stub.post('sentry/api/42/store/') { [403, {}, 'Creation of this event was blocked'] } - end - - logger = Logger.new(StringIO.new) - - Raven.configure do |config| - config.server = 'http://12345:67890@sentry.localdomain/sentry/42' - config.http_adapter = [:test, stubs] - config.logger = logger - end + it "hitting quota limit shouldn't swallow exception" do + @stubs.post('sentry/api/42/store/') { [403, {}, 'Creation of this event was blocked'] } # sentry error and original error - expect(logger).not_to receive(:error).twice - Raven.capture_exception(build_exception) + expect(@logger).not_to receive(:error).twice + @instance.capture_exception(build_exception) - stubs.verify_stubbed_calls + @stubs.verify_stubbed_calls end - example "timed backoff should prevent sends" do - io = StringIO.new - Raven.configure do |config| - config.server = 'http://12345:67890@sentry.localdomain/sentry/42' - config.http_adapter = [:test, nil] - config.logger = Logger.new(io) - end - - expect_any_instance_of(Raven::Transports::HTTP).to receive(:send_event).exactly(1).times.and_raise(Faraday::Error::ConnectionFailed, "conn failed") - 2.times { Raven.capture_exception(build_exception) } - expect(io.string).to match(/Failed to submit event: ZeroDivisionError: divided by 0$/) + it "timed backoff should prevent sends" do + expect(@instance.client.transport).to receive(:send_event).exactly(1).times.and_raise(Faraday::Error::ConnectionFailed, "conn failed") + 2.times { @instance.capture_exception(build_exception) } + expect(@io.string).to match(/Failed to submit event: ZeroDivisionError: divided by 0$/) end - example "transport failure should call transport_failure_callback" do - io = StringIO.new - Raven.configure do |config| - config.server = 'http://12345:67890@sentry.localdomain/sentry/42' - config.http_adapter = [:test, nil] - config.transport_failure_callback = proc { |_e| io.puts "OK!" } - end + it "transport failure should call transport_failure_callback" do + @instance.configuration.transport_failure_callback = proc { |_e| @io.puts "OK!" } - expect_any_instance_of(Raven::Transports::HTTP).to receive(:send_event).exactly(1).times.and_raise(Faraday::Error::ConnectionFailed, "conn failed") - Raven.capture_exception(build_exception) - expect(io.string).to match(/OK!$/) + expect(@instance.client.transport).to receive(:send_event).exactly(1).times.and_raise(Faraday::Error::ConnectionFailed, "conn failed") + @instance.capture_exception(build_exception) + expect(@io.string).to match(/OK!$/) end end diff -Nru ruby-sentry-raven-2.5.1/spec/raven/processors/removestacktrace_spec.rb ruby-sentry-raven-2.6.3/spec/raven/processors/removestacktrace_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/processors/removestacktrace_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/processors/removestacktrace_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -1,6 +1,5 @@ require 'spec_helper' require 'raven/processor/removestacktrace' -require 'active_support/core_ext/hash/keys' describe Raven::Processor::RemoveStacktrace do before do @@ -44,12 +43,14 @@ end end - it 'should remove stacktraces even when keys are strings' do - data = Raven::Event.capture_exception(build_exception).to_hash.deep_stringify_keys + if defined?(Rails) # depends on activesupport + it 'should remove stacktraces even when keys are strings' do + data = Raven::Event.capture_exception(build_exception).to_hash.deep_stringify_keys - expect(data["exception"]["values"][0]["stacktrace"]).to_not eq(nil) - result = @processor.process(data) + expect(data["exception"]["values"][0]["stacktrace"]).to_not eq(nil) + result = @processor.process(data) - expect(result["exception"]["values"][0]["stacktrace"]).to eq(nil) + expect(result["exception"]["values"][0]["stacktrace"]).to eq(nil) + end end end diff -Nru ruby-sentry-raven-2.5.1/spec/raven/processors/sanitizedata_processor_spec.rb ruby-sentry-raven-2.6.3/spec/raven/processors/sanitizedata_processor_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/processors/sanitizedata_processor_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/processors/sanitizedata_processor_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -2,24 +2,41 @@ describe Raven::Processor::SanitizeData do before do - @client = double("client") - allow(@client).to receive_message_chain(:configuration, :sanitize_fields) { ['user_field'] } - allow(@client).to receive_message_chain(:configuration, :sanitize_credit_cards) { true } - @processor = Raven::Processor::SanitizeData.new(@client) + config = Struct.new(:sanitize_fields, :sanitize_credit_cards, :sanitize_fields_excluded).new([], true, []) + client = Struct.new(:configuration).new(config) + @processor = Raven::Processor::SanitizeData.new(client) end context 'configuration for sanitize fields' do it 'should union default sanitize fields with user-defined sanitize fields' do - fields = Raven::Processor::SanitizeData::DEFAULT_FIELDS | %w(test monkeybutt foo(.*)?bar) + fields = Raven::Processor::SanitizeData::DEFAULT_FIELDS | %w(test monkeybutt) @processor.sanitize_fields = fields - expected_fields_re = /authorization|password|passwd|secret|ssn|social(.*)?sec|\btest\b|\bmonkeybutt\b|foo(.*)?bar/i + expected_fields_re = /authorization|password|passwd|secret|ssn|social(.*)?sec|\btest\b|\bmonkeybutt\b/i + + expect(@processor.send(:fields_re)).to eq(expected_fields_re) + end + + it 'should remove default fields if specified by sanitize_fields_excluded' do + @processor.sanitize_fields_excluded = %w(authorization) + + expected_fields_re = /password|passwd|secret|ssn|social(.*)?sec/i + + expect(@processor.send(:fields_re)).to eq(expected_fields_re) + end + + it 'accepts regex-like strings' do + @processor.sanitize_fields = ["foo(.*)?bar"] + + expected_fields_re = /authorization|password|passwd|secret|ssn|social(.*)?sec|foo(.*)?bar/i expect(@processor.send(:fields_re)).to eq(expected_fields_re) end end it 'should filter http data' do + @processor.sanitize_fields = ['user_field'] + data = { 'sentry.interfaces.Http' => { 'data' => { @@ -55,6 +72,8 @@ end it 'should filter json data' do + @processor.sanitize_fields = ['user_field'] + data_with_json = { 'json' => { 'foo' => 'bar', @@ -217,8 +236,5 @@ vars = result["sentry.interfaces.Http"]["data"] expect(vars["query_string"]).to eq(encoded_query_string) end - - it 'handles url encoded values' do - end end end diff -Nru ruby-sentry-raven-2.5.1/spec/raven/processors/utf8conversion_spec.rb ruby-sentry-raven-2.6.3/spec/raven/processors/utf8conversion_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/processors/utf8conversion_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/processors/utf8conversion_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -59,4 +59,15 @@ results = @processor.process(data) expect(results[:key]).to eq(:value) end + + it "deals with unicode hidden in ASCII_8BIT" do + data = ["\xE2\x9C\x89 Hello".force_encoding(Encoding::ASCII_8BIT)] + + results = @processor.process(data) + + # Calling JSON.generate here to simulate this value eventually being fed + # to JSON generator in the client for transport, we're looking to see + # if encoding errors are raised + expect(JSON.generate(results)).to eq("[\"✉ Hello\"]") + end end diff -Nru ruby-sentry-raven-2.5.1/spec/raven/transports/http_spec.rb ruby-sentry-raven-2.6.3/spec/raven/transports/http_spec.rb --- ruby-sentry-raven-2.5.1/spec/raven/transports/http_spec.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/raven/transports/http_spec.rb 2017-08-07 17:22:13.000000000 +0000 @@ -1,24 +1,21 @@ require 'spec_helper' describe Raven::Transports::HTTP do - before do - Raven.configure do |config| - config.server = 'http://12345:67890@sentry.localdomain/sentry/42' - end - end + let(:config) { Raven::Configuration.new.tap { |c| c.dsn = 'http://12345:67890@sentry.localdomain/sentry/42' } } + let(:client) { Raven::Client.new(config) } it 'should set a custom User-Agent' do - expect(Raven.client.send(:transport).conn.headers[:user_agent]).to eq("sentry-ruby/#{Raven::VERSION}") + expect(client.send(:transport).conn.headers[:user_agent]).to eq("sentry-ruby/#{Raven::VERSION}") end it 'should raise an error on 4xx responses' do stubs = Faraday::Adapter::Test::Stubs.new do |stub| stub.post('sentry/api/42/store/') { [404, {}, 'not found'] } end - Raven.configure { |config| config.http_adapter = [:test, stubs] } + client.configuration.http_adapter = [:test, stubs] event = JSON.generate(Raven::Event.from_message("test").to_hash) - expect { Raven.client.send(:transport).send_event("test", event) }.to raise_error(Raven::Error) + expect { client.send(:transport).send_event("test", event) }.to raise_error(Raven::Error) stubs.verify_stubbed_calls end @@ -27,10 +24,10 @@ stubs = Faraday::Adapter::Test::Stubs.new do |stub| stub.post('sentry/api/42/store/') { [500, {}, 'error'] } end - Raven.configure { |config| config.http_adapter = [:test, stubs] } + client.configuration.http_adapter = [:test, stubs] event = JSON.generate(Raven::Event.from_message("test").to_hash) - expect { Raven.client.send(:transport).send_event("test", event) }.to raise_error(Raven::Error) + expect { client.send(:transport).send_event("test", event) }.to raise_error(Raven::Error) stubs.verify_stubbed_calls end @@ -39,10 +36,10 @@ stubs = Faraday::Adapter::Test::Stubs.new do |stub| stub.post('sentry/api/42/store/') { [400, { 'x-sentry-error' => 'error_in_header' }, 'error'] } end - Raven.configure { |config| config.http_adapter = [:test, stubs] } + client.configuration.http_adapter = [:test, stubs] event = JSON.generate(Raven::Event.from_message("test").to_hash) - expect { Raven.client.send(:transport).send_event("test", event) }.to raise_error(Raven::Error, /error_in_header/) + expect { client.send(:transport).send_event("test", event) }.to raise_error(Raven::Error, /error_in_header/) stubs.verify_stubbed_calls end @@ -51,11 +48,9 @@ builder = spy('faraday_builder') expect(Faraday).to receive(:new).and_yield(builder) - Raven.configure do |config| - config.faraday_builder = proc { |b| b.request :instrumentation } - end + client.configuration.faraday_builder = proc { |b| b.request :instrumentation } - Raven.client.send(:transport) + client.send(:transport) expect(builder).to have_received(:request).with(:instrumentation) end diff -Nru ruby-sentry-raven-2.5.1/spec/spec_helper.rb ruby-sentry-raven-2.6.3/spec/spec_helper.rb --- ruby-sentry-raven-2.5.1/spec/spec_helper.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/spec_helper.rb 2017-08-07 17:22:13.000000000 +0000 @@ -1,7 +1,21 @@ require 'sentry-raven-without-integrations' +require 'raven/transports/dummy' -require File.dirname(__FILE__) + "/support/test_rails_app/app.rb" -require "rspec/rails" +Raven.configure do |config| + config.dsn = "dummy://12345:67890@sentry.localdomain/sentry/42" + config.encoding = "json" + config.silence_ready = true + config.logger = Logger.new(nil) +end + +if ENV["RAILS_VERSION"] && (ENV["RAILS_VERSION"].to_i == 0) + RSpec.configure do |config| + config.filter_run_excluding :rails => true + end +else + require File.dirname(__FILE__) + "/support/test_rails_app/app.rb" + require "rspec/rails" +end RSpec.configure do |config| config.mock_with(:rspec) { |mocks| mocks.verify_partial_doubles = true } diff -Nru ruby-sentry-raven-2.5.1/spec/support/Rakefile ruby-sentry-raven-2.6.3/spec/support/Rakefile --- ruby-sentry-raven-2.5.1/spec/support/Rakefile 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/support/Rakefile 2017-08-07 17:22:13.000000000 +0000 @@ -1,7 +1,6 @@ require 'rake' require 'rubygems' require 'raven' -require 'raven/transports/dummy' Raven.configure do |config| config.dsn = 'dummy://12345:67890@sentry.localdomain/sentry/42' diff -Nru ruby-sentry-raven-2.5.1/spec/support/test_rails_app/app.rb ruby-sentry-raven-2.6.3/spec/support/test_rails_app/app.rb --- ruby-sentry-raven-2.5.1/spec/support/test_rails_app/app.rb 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/spec/support/test_rails_app/app.rb 2017-08-07 17:22:13.000000000 +0000 @@ -1,10 +1,9 @@ require 'rails' -# require "active_model/railtie" -# require "active_job/railtie" # require "active_record/railtie" +require "action_view/railtie" require "action_controller/railtie" # require "action_mailer/railtie" -require "action_view/railtie" +require "active_job/railtie" # require "action_cable/engine" # require "sprockets/railtie" # require "rails/test_unit/railtie" diff -Nru ruby-sentry-raven-2.5.1/.travis.yml ruby-sentry-raven-2.6.3/.travis.yml --- ruby-sentry-raven-2.5.1/.travis.yml 2017-05-24 14:06:15.000000000 +0000 +++ ruby-sentry-raven-2.6.3/.travis.yml 2017-08-07 17:22:13.000000000 +0000 @@ -8,15 +8,14 @@ only: [master] rvm: - - 1.9 - 2.2.7 - 2.3.4 - - ruby-head - 2.4.1 -gemfile: - - gemfiles/rails42.gemfile - - gemfiles/rails5.gemfile +env: + - RAILS_VERSION=4 + - RAILS_VERSION=5 + - RAILS_VERSION=0 addons: apt: @@ -28,23 +27,15 @@ matrix: include: - - rvm: jruby-1.7.26 - env: JRUBY_OPTS="--dev" - gemfile: gemfiles/rails42.gemfile - - rvm: jruby-9.1.8.0 - env: JRUBY_OPTS="--dev -J-Djruby.launch.inproc=true -J-Xmx1024M" - gemfile: gemfiles/rails42.gemfile - - rvm: jruby-9.1.8.0 - env: JRUBY_OPTS="--dev -J-Djruby.launch.inproc=true -J-Xmx1024M" - gemfile: gemfiles/rails5.gemfile - allow_failures: + - rvm: 1.9 + env: RAILS_VERSION=4 + - rvm: jruby-1.7.27 + env: JRUBY_OPTS="--dev" RAILS_VERSION=4 + - rvm: jruby-9.1.12.0 + env: JRUBY_OPTS="--dev -J-Djruby.launch.inproc=true -J-Xmx1024M" RAILS_VERSION=4 + - rvm: jruby-9.1.12.0 + env: JRUBY_OPTS="--dev -J-Djruby.launch.inproc=true -J-Xmx1024M" RAILS_VERSION=5 - rvm: ruby-head - exclude: - - rvm: 2.2.7 - gemfile: gemfiles/rails32.gemfile + env: RAILS_VERSION=0 + allow_failures: - rvm: ruby-head - gemfile: gemfiles/rails32.gemfile - - rvm: 2.4.1 - gemfile: gemfiles/rails32.gemfile - - rvm: 1.9 - gemfile: gemfiles/rails5.gemfile