sentry-raven 3.1.1 → 3.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.craft.yml +9 -5
- data/.scripts/bump-version.rb +5 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +5 -1
- data/Makefile +3 -0
- data/README.md +19 -7
- data/lib/raven/base.rb +1 -0
- data/lib/raven/configuration.rb +0 -1
- data/lib/raven/event.rb +5 -1
- data/lib/raven/instance.rb +7 -1
- data/lib/raven/integrations/delayed_job.rb +1 -1
- data/lib/raven/integrations/rack.rb +2 -14
- data/lib/raven/transports/http.rb +2 -1
- data/lib/raven/utils/request_id.rb +16 -0
- data/lib/raven/version.rb +1 -1
- data/sentry-raven.gemspec +7 -0
- metadata +10 -148
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -32
- data/.github/pull_request_template.md +0 -16
- data/.github/workflows/test.yml +0 -92
- data/.github/workflows/zeus_upload.yml +0 -32
- data/.gitignore +0 -16
- data/.gitmodules +0 -0
- data/.rspec +0 -1
- data/.rubocop.yml +0 -112
- data/.scripts/bump-version.sh +0 -9
- data/CONTRIBUTING.md +0 -71
- data/sentry-ruby/.gitignore +0 -11
- data/sentry-ruby/.rspec +0 -3
- data/sentry-ruby/.travis.yml +0 -6
- data/sentry-ruby/CODE_OF_CONDUCT.md +0 -74
- data/sentry-ruby/Gemfile +0 -9
- data/sentry-ruby/LICENSE.txt +0 -21
- data/sentry-ruby/README.md +0 -44
- data/sentry-ruby/Rakefile +0 -6
- data/sentry-ruby/bin/console +0 -14
- data/sentry-ruby/bin/setup +0 -8
- data/sentry-ruby/examples/rails-6.0/.browserslistrc +0 -1
- data/sentry-ruby/examples/rails-6.0/.gitignore +0 -35
- data/sentry-ruby/examples/rails-6.0/Gemfile +0 -58
- data/sentry-ruby/examples/rails-6.0/README.md +0 -23
- data/sentry-ruby/examples/rails-6.0/Rakefile +0 -6
- data/sentry-ruby/examples/rails-6.0/app/assets/config/manifest.js +0 -2
- data/sentry-ruby/examples/rails-6.0/app/assets/images/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/app/assets/stylesheets/application.css +0 -15
- data/sentry-ruby/examples/rails-6.0/app/channels/application_cable/channel.rb +0 -4
- data/sentry-ruby/examples/rails-6.0/app/channels/application_cable/connection.rb +0 -4
- data/sentry-ruby/examples/rails-6.0/app/controllers/application_controller.rb +0 -2
- data/sentry-ruby/examples/rails-6.0/app/controllers/concerns/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/app/controllers/welcome_controller.rb +0 -23
- data/sentry-ruby/examples/rails-6.0/app/helpers/application_helper.rb +0 -2
- data/sentry-ruby/examples/rails-6.0/app/javascript/channels/consumer.js +0 -6
- data/sentry-ruby/examples/rails-6.0/app/javascript/channels/index.js +0 -5
- data/sentry-ruby/examples/rails-6.0/app/javascript/packs/application.js +0 -17
- data/sentry-ruby/examples/rails-6.0/app/jobs/application_job.rb +0 -7
- data/sentry-ruby/examples/rails-6.0/app/mailers/application_mailer.rb +0 -4
- data/sentry-ruby/examples/rails-6.0/app/models/application_record.rb +0 -3
- data/sentry-ruby/examples/rails-6.0/app/models/concerns/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/app/views/layouts/application.html.erb +0 -15
- data/sentry-ruby/examples/rails-6.0/app/views/layouts/mailer.html.erb +0 -13
- data/sentry-ruby/examples/rails-6.0/app/views/layouts/mailer.text.erb +0 -1
- data/sentry-ruby/examples/rails-6.0/app/views/welcome/report_demo.html.erb +0 -22
- data/sentry-ruby/examples/rails-6.0/app/views/welcome/view_error.html.erb +0 -1
- data/sentry-ruby/examples/rails-6.0/app/workers/error_worker.rb +0 -7
- data/sentry-ruby/examples/rails-6.0/babel.config.js +0 -72
- data/sentry-ruby/examples/rails-6.0/bin/bundle +0 -114
- data/sentry-ruby/examples/rails-6.0/bin/rails +0 -9
- data/sentry-ruby/examples/rails-6.0/bin/rake +0 -9
- data/sentry-ruby/examples/rails-6.0/bin/setup +0 -36
- data/sentry-ruby/examples/rails-6.0/bin/spring +0 -17
- data/sentry-ruby/examples/rails-6.0/bin/webpack +0 -18
- data/sentry-ruby/examples/rails-6.0/bin/webpack-dev-server +0 -18
- data/sentry-ruby/examples/rails-6.0/bin/yarn +0 -11
- data/sentry-ruby/examples/rails-6.0/config.ru +0 -5
- data/sentry-ruby/examples/rails-6.0/config/application.rb +0 -28
- data/sentry-ruby/examples/rails-6.0/config/boot.rb +0 -4
- data/sentry-ruby/examples/rails-6.0/config/cable.yml +0 -10
- data/sentry-ruby/examples/rails-6.0/config/credentials.yml.enc +0 -1
- data/sentry-ruby/examples/rails-6.0/config/database.yml +0 -25
- data/sentry-ruby/examples/rails-6.0/config/environment.rb +0 -5
- data/sentry-ruby/examples/rails-6.0/config/environments/development.rb +0 -62
- data/sentry-ruby/examples/rails-6.0/config/environments/production.rb +0 -112
- data/sentry-ruby/examples/rails-6.0/config/environments/test.rb +0 -48
- data/sentry-ruby/examples/rails-6.0/config/initializers/application_controller_renderer.rb +0 -8
- data/sentry-ruby/examples/rails-6.0/config/initializers/assets.rb +0 -14
- data/sentry-ruby/examples/rails-6.0/config/initializers/backtrace_silencers.rb +0 -7
- data/sentry-ruby/examples/rails-6.0/config/initializers/content_security_policy.rb +0 -30
- data/sentry-ruby/examples/rails-6.0/config/initializers/cookies_serializer.rb +0 -5
- data/sentry-ruby/examples/rails-6.0/config/initializers/filter_parameter_logging.rb +0 -4
- data/sentry-ruby/examples/rails-6.0/config/initializers/inflections.rb +0 -16
- data/sentry-ruby/examples/rails-6.0/config/initializers/mime_types.rb +0 -4
- data/sentry-ruby/examples/rails-6.0/config/initializers/wrap_parameters.rb +0 -14
- data/sentry-ruby/examples/rails-6.0/config/locales/en.yml +0 -33
- data/sentry-ruby/examples/rails-6.0/config/puma.rb +0 -38
- data/sentry-ruby/examples/rails-6.0/config/routes.rb +0 -10
- data/sentry-ruby/examples/rails-6.0/config/spring.rb +0 -6
- data/sentry-ruby/examples/rails-6.0/config/storage.yml +0 -34
- data/sentry-ruby/examples/rails-6.0/config/webpack/development.js +0 -5
- data/sentry-ruby/examples/rails-6.0/config/webpack/environment.js +0 -3
- data/sentry-ruby/examples/rails-6.0/config/webpack/production.js +0 -5
- data/sentry-ruby/examples/rails-6.0/config/webpack/test.js +0 -5
- data/sentry-ruby/examples/rails-6.0/config/webpacker.yml +0 -96
- data/sentry-ruby/examples/rails-6.0/db/seeds.rb +0 -7
- data/sentry-ruby/examples/rails-6.0/lib/assets/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/lib/tasks/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/package.json +0 -15
- data/sentry-ruby/examples/rails-6.0/postcss.config.js +0 -12
- data/sentry-ruby/examples/rails-6.0/public/404.html +0 -67
- data/sentry-ruby/examples/rails-6.0/public/422.html +0 -67
- data/sentry-ruby/examples/rails-6.0/public/500.html +0 -66
- data/sentry-ruby/examples/rails-6.0/public/apple-touch-icon-precomposed.png +0 -0
- data/sentry-ruby/examples/rails-6.0/public/apple-touch-icon.png +0 -0
- data/sentry-ruby/examples/rails-6.0/public/favicon.ico +0 -0
- data/sentry-ruby/examples/rails-6.0/public/robots.txt +0 -1
- data/sentry-ruby/examples/rails-6.0/storage/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/test/application_system_test_case.rb +0 -5
- data/sentry-ruby/examples/rails-6.0/test/channels/application_cable/connection_test.rb +0 -11
- data/sentry-ruby/examples/rails-6.0/test/controllers/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/test/fixtures/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/test/fixtures/files/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/test/helpers/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/test/integration/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/test/mailers/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/test/models/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/test/system/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/test/test_helper.rb +0 -13
- data/sentry-ruby/examples/rails-6.0/vendor/.keep +0 -0
- data/sentry-ruby/examples/rails-6.0/yarn.lock +0 -7508
- data/sentry-ruby/lib/sentry.rb +0 -16
- data/sentry-ruby/lib/sentry/backtrace.rb +0 -128
- data/sentry-ruby/lib/sentry/client.rb +0 -162
- data/sentry-ruby/lib/sentry/client/state.rb +0 -40
- data/sentry-ruby/lib/sentry/configuration.rb +0 -533
- data/sentry-ruby/lib/sentry/event.rb +0 -209
- data/sentry-ruby/lib/sentry/interface.rb +0 -31
- data/sentry-ruby/lib/sentry/interfaces/exception.rb +0 -15
- data/sentry-ruby/lib/sentry/interfaces/http.rb +0 -16
- data/sentry-ruby/lib/sentry/interfaces/message.rb +0 -18
- data/sentry-ruby/lib/sentry/interfaces/single_exception.rb +0 -14
- data/sentry-ruby/lib/sentry/interfaces/stack_trace.rb +0 -69
- data/sentry-ruby/lib/sentry/linecache.rb +0 -44
- data/sentry-ruby/lib/sentry/logger.rb +0 -20
- data/sentry-ruby/lib/sentry/transports.rb +0 -19
- data/sentry-ruby/lib/sentry/transports/dummy.rb +0 -16
- data/sentry-ruby/lib/sentry/transports/http.rb +0 -66
- data/sentry-ruby/lib/sentry/transports/stdout.rb +0 -20
- data/sentry-ruby/lib/sentry/utils/deep_merge.rb +0 -22
- data/sentry-ruby/lib/sentry/utils/exception_cause_chain.rb +0 -20
- data/sentry-ruby/lib/sentry/version.rb +0 -3
- data/sentry-ruby/sentry-ruby.gemspec +0 -26
- data/sentry-ruby/spec/sentry/backtrace_spec.rb +0 -38
- data/sentry-ruby/spec/sentry/client_spec.rb +0 -443
- data/sentry-ruby/spec/sentry/configuration_spec.rb +0 -400
- data/sentry-ruby/spec/sentry/event_spec.rb +0 -238
- data/sentry-ruby/spec/sentry/interface_spec.rb +0 -38
- data/sentry-ruby/spec/sentry/interfaces/stack_trace_spec.rb +0 -11
- data/sentry-ruby/spec/sentry/linecache_spec.rb +0 -40
- data/sentry-ruby/spec/sentry/transports/http_spec.rb +0 -57
- data/sentry-ruby/spec/sentry/transports/stdout_spec.rb +0 -11
- data/sentry-ruby/spec/sentry_spec.rb +0 -9
- data/sentry-ruby/spec/spec_helper.rb +0 -49
- data/sentry-ruby/spec/support/linecache.txt +0 -6
@@ -1,19 +0,0 @@
|
|
1
|
-
module Sentry
|
2
|
-
module Transports
|
3
|
-
class Transport
|
4
|
-
attr_accessor :configuration
|
5
|
-
|
6
|
-
def initialize(configuration)
|
7
|
-
@configuration = configuration
|
8
|
-
end
|
9
|
-
|
10
|
-
def send_event # (auth_header, data, options = {})
|
11
|
-
raise NotImplementedError, 'Abstract method not implemented'
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
require "sentry/transports/dummy"
|
18
|
-
require "sentry/transports/http"
|
19
|
-
require "sentry/transports/stdout"
|
@@ -1,16 +0,0 @@
|
|
1
|
-
module Sentry
|
2
|
-
module Transports
|
3
|
-
class Dummy < Transport
|
4
|
-
attr_accessor :events
|
5
|
-
|
6
|
-
def initialize(*)
|
7
|
-
super
|
8
|
-
@events = []
|
9
|
-
end
|
10
|
-
|
11
|
-
def send_event(auth_header, data, options = {})
|
12
|
-
@events << [auth_header, data, options]
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require 'faraday'
|
2
|
-
|
3
|
-
module Sentry
|
4
|
-
module Transports
|
5
|
-
class HTTP < Transport
|
6
|
-
attr_accessor :conn, :adapter
|
7
|
-
|
8
|
-
def initialize(*args)
|
9
|
-
super
|
10
|
-
self.adapter = configuration.http_adapter || Faraday.default_adapter
|
11
|
-
self.conn = set_conn
|
12
|
-
end
|
13
|
-
|
14
|
-
def send_event(auth_header, data, options = {})
|
15
|
-
unless configuration.sending_allowed?
|
16
|
-
logger.debug("Event not sent: #{configuration.error_messages}")
|
17
|
-
end
|
18
|
-
|
19
|
-
project_id = configuration[:project_id]
|
20
|
-
path = configuration[:path] + "/"
|
21
|
-
|
22
|
-
conn.post "#{path}api/#{project_id}/store/" do |req|
|
23
|
-
req.headers['Content-Type'] = options[:content_type]
|
24
|
-
req.headers['X-Sentry-Auth'] = auth_header
|
25
|
-
req.body = data
|
26
|
-
end
|
27
|
-
rescue Faraday::Error => e
|
28
|
-
error_info = e.message
|
29
|
-
if e.response && e.response[:headers]['x-sentry-error']
|
30
|
-
error_info += " Error in headers is: #{e.response[:headers]['x-sentry-error']}"
|
31
|
-
end
|
32
|
-
raise Sentry::Error, error_info
|
33
|
-
end
|
34
|
-
|
35
|
-
private
|
36
|
-
|
37
|
-
def set_conn
|
38
|
-
configuration.logger.debug "Sentry HTTP Transport connecting to #{configuration.server}"
|
39
|
-
|
40
|
-
proxy = configuration.public_send(:proxy)
|
41
|
-
|
42
|
-
Faraday.new(configuration.server, :ssl => ssl_configuration, :proxy => proxy) do |builder|
|
43
|
-
configuration.faraday_builder&.call(builder)
|
44
|
-
builder.response :raise_error
|
45
|
-
builder.options.merge! faraday_opts
|
46
|
-
builder.headers[:user_agent] = "sentry-ruby/#{Sentry::VERSION}"
|
47
|
-
builder.adapter(*adapter)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
# TODO: deprecate and replace where possible w/Faraday Builder
|
52
|
-
def faraday_opts
|
53
|
-
[:timeout, :open_timeout].each_with_object({}) do |opt, memo|
|
54
|
-
memo[opt] = configuration.public_send(opt) if configuration.public_send(opt)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
def ssl_configuration
|
59
|
-
(configuration.ssl || {}).merge(
|
60
|
-
:verify => configuration.ssl_verification,
|
61
|
-
:ca_file => configuration.ssl_ca_file
|
62
|
-
)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Sentry
|
2
|
-
module Transports
|
3
|
-
class Stdout < Transport
|
4
|
-
attr_accessor :events
|
5
|
-
|
6
|
-
def initialize(*)
|
7
|
-
super
|
8
|
-
end
|
9
|
-
|
10
|
-
def send_event(_auth_header, data, _options = {})
|
11
|
-
unless configuration.sending_allowed?
|
12
|
-
logger.debug("Event not sent: #{configuration.error_messages}")
|
13
|
-
end
|
14
|
-
|
15
|
-
$stdout.puts data
|
16
|
-
$stdout.flush
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module Sentry
|
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
|
-
hash.merge!(other_hash) do |key, this_val, other_val|
|
11
|
-
if this_val.is_a?(Hash) && other_val.is_a?(Hash)
|
12
|
-
deep_merge(this_val, other_val, &block)
|
13
|
-
elsif block_given?
|
14
|
-
block.call(key, this_val, other_val)
|
15
|
-
else
|
16
|
-
other_val
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Sentry
|
2
|
-
module Utils
|
3
|
-
module ExceptionCauseChain
|
4
|
-
def self.exception_to_array(exception)
|
5
|
-
if exception.respond_to?(:cause) && exception.cause
|
6
|
-
exceptions = [exception]
|
7
|
-
while exception.cause
|
8
|
-
exception = exception.cause
|
9
|
-
break if exceptions.any? { |e| e.object_id == exception.object_id }
|
10
|
-
|
11
|
-
exceptions << exception
|
12
|
-
end
|
13
|
-
exceptions
|
14
|
-
else
|
15
|
-
[exception]
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
require_relative 'lib/sentry/version'
|
2
|
-
|
3
|
-
Gem::Specification.new do |spec|
|
4
|
-
spec.name = "sentry-ruby"
|
5
|
-
spec.version = Sentry::VERSION
|
6
|
-
spec.authors = ["Sentry Team"]
|
7
|
-
spec.description = spec.summary = "A gem that provides a client interface for the Sentry error logger"
|
8
|
-
spec.email = "accounts@sentry.io"
|
9
|
-
spec.license = 'Apache-2.0'
|
10
|
-
spec.homepage = "https://github.com/getsentry/raven-ruby"
|
11
|
-
|
12
|
-
spec.platform = Gem::Platform::RUBY
|
13
|
-
spec.required_ruby_version = '>= 2.4'
|
14
|
-
spec.extra_rdoc_files = ["README.md", "LICENSE"]
|
15
|
-
spec.files = `git ls-files | grep -Ev '^(spec|benchmarks|examples)'`.split("\n")
|
16
|
-
|
17
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
18
|
-
spec.metadata["source_code_uri"] = spec.homepage
|
19
|
-
spec.metadata["changelog_uri"] = "#{spec.homepage}/blob/master/CHANGELOG.md"
|
20
|
-
|
21
|
-
spec.bindir = "exe"
|
22
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
|
-
spec.require_paths = ["lib"]
|
24
|
-
|
25
|
-
spec.add_dependency "faraday", ">= 1.0"
|
26
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
RSpec.describe Sentry::Backtrace do
|
4
|
-
let(:configuration) { Sentry::Configuration.new }
|
5
|
-
|
6
|
-
before(:each) do
|
7
|
-
@backtrace = Sentry::Backtrace.parse(Thread.current.backtrace, configuration: configuration)
|
8
|
-
end
|
9
|
-
|
10
|
-
it "calls backtrace_cleanup_callback if it's present in the configuration" do
|
11
|
-
called = false
|
12
|
-
callback = proc do |backtrace|
|
13
|
-
called = true
|
14
|
-
backtrace
|
15
|
-
end
|
16
|
-
configuration.backtrace_cleanup_callback = callback
|
17
|
-
Sentry::Backtrace.parse(Thread.current.backtrace, configuration: configuration)
|
18
|
-
|
19
|
-
expect(called).to eq(true)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "#lines" do
|
23
|
-
expect(@backtrace.lines.first).to be_a(Sentry::Backtrace::Line)
|
24
|
-
end
|
25
|
-
|
26
|
-
it "#inspect" do
|
27
|
-
expect(@backtrace.inspect).to match(/Backtrace: .*>$/)
|
28
|
-
end
|
29
|
-
|
30
|
-
it "#to_s" do
|
31
|
-
expect(@backtrace.to_s).to match(/backtrace_spec.rb:\d/)
|
32
|
-
end
|
33
|
-
|
34
|
-
it "==" do
|
35
|
-
@backtrace2 = Sentry::Backtrace.new(@backtrace.lines)
|
36
|
-
expect(@backtrace).to be == @backtrace2
|
37
|
-
end
|
38
|
-
end
|
@@ -1,443 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
class ExceptionWithContext < StandardError
|
4
|
-
def sentry_context
|
5
|
-
{ extra: {
|
6
|
-
'context_event_key' => 'context_value',
|
7
|
-
'context_key' => 'context_value'
|
8
|
-
} }
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
RSpec.describe Sentry::Client do
|
13
|
-
let(:configuration) do
|
14
|
-
Sentry::Configuration.new.tap do |config|
|
15
|
-
config.server = 'http://12345:67890@sentry.localdomain/sentry/42'
|
16
|
-
end
|
17
|
-
end
|
18
|
-
let(:fake_time) { Time.now }
|
19
|
-
|
20
|
-
subject { Sentry::Client.new(configuration) }
|
21
|
-
|
22
|
-
before do
|
23
|
-
allow(Time).to receive(:now).and_return fake_time
|
24
|
-
end
|
25
|
-
|
26
|
-
describe "#generate_auth_header" do
|
27
|
-
it "generates an auth header" do
|
28
|
-
expect(subject.send(:generate_auth_header)).to eq(
|
29
|
-
"Sentry sentry_version=5, sentry_client=sentry-ruby/#{Sentry::VERSION}, sentry_timestamp=#{fake_time.to_i}, " \
|
30
|
-
"sentry_key=12345, sentry_secret=67890"
|
31
|
-
)
|
32
|
-
end
|
33
|
-
|
34
|
-
it "generates an auth header without a secret (Sentry 9)" do
|
35
|
-
configuration.server = "https://66260460f09b5940498e24bb7ce093a0@sentry.io/42"
|
36
|
-
|
37
|
-
expect(subject.send(:generate_auth_header)).to eq(
|
38
|
-
"Sentry sentry_version=5, sentry_client=sentry-ruby/#{Sentry::VERSION}, sentry_timestamp=#{fake_time.to_i}, " \
|
39
|
-
"sentry_key=66260460f09b5940498e24bb7ce093a0"
|
40
|
-
)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
describe "#send_event" do
|
45
|
-
let(:event) { subject.event_from_exception(ZeroDivisionError.new("divided by 0")) }
|
46
|
-
|
47
|
-
context "when success" do
|
48
|
-
before do
|
49
|
-
allow(subject.transport).to receive(:send_event)
|
50
|
-
end
|
51
|
-
|
52
|
-
it "sends Event object" do
|
53
|
-
expect(subject).not_to receive(:failed_send)
|
54
|
-
|
55
|
-
expect(subject.send_event(event)).to eq(event.to_hash)
|
56
|
-
end
|
57
|
-
|
58
|
-
it "sends Event hash" do
|
59
|
-
expect(subject).not_to receive(:failed_send)
|
60
|
-
|
61
|
-
expect(subject.send_event(event.to_json_compatible)).to eq(event.to_json_compatible)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
context "when failed" do
|
66
|
-
let(:logger) { spy }
|
67
|
-
|
68
|
-
before do
|
69
|
-
configuration.logger = logger
|
70
|
-
allow(subject.transport).to receive(:send_event).and_raise(StandardError)
|
71
|
-
|
72
|
-
expect(logger).to receive(:warn).exactly(2)
|
73
|
-
end
|
74
|
-
|
75
|
-
it "sends Event object" do
|
76
|
-
expect(subject.send_event(event)).to eq(nil)
|
77
|
-
end
|
78
|
-
|
79
|
-
it "sends Event hash" do
|
80
|
-
expect(subject.send_event(event.to_json_compatible)).to eq(nil)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
describe "#transport" do
|
86
|
-
context "when scheme is not set" do
|
87
|
-
it "returns HTTP transport object" do
|
88
|
-
expect(subject.transport).to be_a(Sentry::Transports::HTTP)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context "when scheme is http" do
|
93
|
-
before do
|
94
|
-
configuration.scheme = "http"
|
95
|
-
end
|
96
|
-
|
97
|
-
it "returns HTTP transport object" do
|
98
|
-
expect(subject.transport).to be_a(Sentry::Transports::HTTP)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
context "when scheme is https" do
|
103
|
-
before do
|
104
|
-
configuration.scheme = "https"
|
105
|
-
end
|
106
|
-
|
107
|
-
it "returns HTTP transport object" do
|
108
|
-
expect(subject.transport).to be_a(Sentry::Transports::HTTP)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
context "when scheme is dummy" do
|
113
|
-
before do
|
114
|
-
configuration.scheme = "dummy"
|
115
|
-
end
|
116
|
-
|
117
|
-
it "returns Dummy transport object" do
|
118
|
-
expect(subject.transport).to be_a(Sentry::Transports::Dummy)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
context "when scheme is stdout" do
|
123
|
-
before do
|
124
|
-
configuration.scheme = "stdout"
|
125
|
-
end
|
126
|
-
|
127
|
-
it "returns Stdout transport object" do
|
128
|
-
expect(subject.transport).to be_a(Sentry::Transports::Stdout)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
shared_examples "options" do
|
134
|
-
let(:options) do
|
135
|
-
{
|
136
|
-
checksum: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
|
137
|
-
release: '1.0',
|
138
|
-
fingerprint: ['{{ default }}', 'foo'],
|
139
|
-
backtrace: ["/path/to/some/file:22:in `function_name'", "/some/other/path:1412:in `other_function'"]
|
140
|
-
}
|
141
|
-
end
|
142
|
-
|
143
|
-
let(:event) do
|
144
|
-
subject.event_from_exception(Exception.new, **options)
|
145
|
-
end
|
146
|
-
|
147
|
-
it 'takes and sets all available options' do
|
148
|
-
expect(event.checksum).to eq('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa')
|
149
|
-
expect(event.release).to eq('1.0')
|
150
|
-
expect(event.fingerprint).to eq(['{{ default }}', 'foo'])
|
151
|
-
end
|
152
|
-
|
153
|
-
it "contains given backtrace" do
|
154
|
-
expect(event[:stacktrace]).to be_a(Sentry::StacktraceInterface)
|
155
|
-
|
156
|
-
frames = event[:stacktrace].to_hash[:frames]
|
157
|
-
expect(frames.length).to eq(2)
|
158
|
-
expect(frames[0][:lineno]).to eq(1412)
|
159
|
-
expect(frames[0][:function]).to eq('other_function')
|
160
|
-
expect(frames[0][:filename]).to eq('/some/other/path')
|
161
|
-
|
162
|
-
expect(frames[1][:lineno]).to eq(22)
|
163
|
-
expect(frames[1][:function]).to eq('function_name')
|
164
|
-
expect(frames[1][:filename]).to eq('/path/to/some/file')
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
describe '#event_from_message' do
|
169
|
-
let(:message) { 'This is a message' }
|
170
|
-
|
171
|
-
it 'returns an event' do
|
172
|
-
event = subject.event_from_message(message)
|
173
|
-
hash = event.to_hash
|
174
|
-
|
175
|
-
expect(event).to be_a(Sentry::Event)
|
176
|
-
expect(hash[:message]).to eq(message)
|
177
|
-
expect(hash[:level]).to eq(:error)
|
178
|
-
end
|
179
|
-
|
180
|
-
it "doesn't change the option hash" do
|
181
|
-
h_int = { abc: :abc }
|
182
|
-
h = { k1: h_int, k2: h_int }
|
183
|
-
subject.event_from_message "Test extra", extra: { h1: h, h2: h_int }
|
184
|
-
|
185
|
-
expect(h).to eq({ k1: h_int, k2: h_int })
|
186
|
-
end
|
187
|
-
|
188
|
-
it_behaves_like "options"
|
189
|
-
end
|
190
|
-
|
191
|
-
describe "#event_from_exception" do
|
192
|
-
let(:message) { 'This is a message' }
|
193
|
-
let(:exception) { Exception.new(message) }
|
194
|
-
let(:event) { subject.event_from_exception(exception) }
|
195
|
-
let(:hash) { event.to_hash }
|
196
|
-
|
197
|
-
before do
|
198
|
-
configuration.scheme = "dummy"
|
199
|
-
end
|
200
|
-
|
201
|
-
it "sets the message to the exception's value and type" do
|
202
|
-
expect(hash[:exception][:values][0][:type]).to eq("Exception")
|
203
|
-
expect(hash[:exception][:values][0][:value]).to eq(message)
|
204
|
-
end
|
205
|
-
|
206
|
-
it 'has level ERROR' do
|
207
|
-
expect(hash[:level]).to eq(:error)
|
208
|
-
end
|
209
|
-
|
210
|
-
it 'does not belong to a module' do
|
211
|
-
expect(hash[:exception][:values][0][:module]).to eq('')
|
212
|
-
end
|
213
|
-
|
214
|
-
it 'returns an event' do
|
215
|
-
event = subject.event_from_exception(ZeroDivisionError.new("divided by 0"))
|
216
|
-
expect(event).to be_a(Sentry::Event)
|
217
|
-
expect(subject.send(:get_message_from_exception, event.to_hash)).to eq("ZeroDivisionError: divided by 0")
|
218
|
-
end
|
219
|
-
|
220
|
-
it_behaves_like "options"
|
221
|
-
|
222
|
-
describe "options - message" do
|
223
|
-
it "proceses string message correctly" do
|
224
|
-
event = subject.event_from_exception(ExceptionWithContext.new, message: "MSG")
|
225
|
-
expect(event.message).to eq("MSG")
|
226
|
-
end
|
227
|
-
|
228
|
-
it "slices long string message" do
|
229
|
-
event = subject.event_from_exception(ExceptionWithContext.new, message: "MSG" * 3000)
|
230
|
-
expect(event.message.length).to eq(8192)
|
231
|
-
end
|
232
|
-
|
233
|
-
it "converts non-string message into string" do
|
234
|
-
expect(configuration.logger).to receive(:debug).with("You're passing a non-string message")
|
235
|
-
|
236
|
-
event = subject.event_from_exception(ExceptionWithContext.new, message: { foo: "bar" })
|
237
|
-
expect(event.message).to eq("{:foo=>\"bar\"}")
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
context 'for a nested exception type' do
|
242
|
-
module Sentry::Test
|
243
|
-
class Exception < RuntimeError; end
|
244
|
-
end
|
245
|
-
let(:exception) { Sentry::Test::Exception.new(message) }
|
246
|
-
|
247
|
-
it 'sends the module name as part of the exception info' do
|
248
|
-
expect(hash[:exception][:values][0][:module]).to eq('Sentry::Test')
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
describe "exception types test" do
|
253
|
-
context 'for a Sentry::Error' do
|
254
|
-
let(:exception) { Sentry::Error.new }
|
255
|
-
it 'does not create an event' do
|
256
|
-
expect(subject.event_from_exception(exception)).to be_nil
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
context 'for an excluded exception type' do
|
261
|
-
module Sentry::Test
|
262
|
-
class BaseExc < RuntimeError; end
|
263
|
-
class SubExc < BaseExc; end
|
264
|
-
module ExcTag; end
|
265
|
-
end
|
266
|
-
|
267
|
-
let(:config) { subject.configuration }
|
268
|
-
|
269
|
-
context "invalid exclusion type" do
|
270
|
-
it 'returns Sentry::Event' do
|
271
|
-
config.excluded_exceptions << nil
|
272
|
-
config.excluded_exceptions << 1
|
273
|
-
config.excluded_exceptions << {}
|
274
|
-
expect(subject.event_from_exception(Sentry::Test::BaseExc.new)).to be_a(Sentry::Event)
|
275
|
-
end
|
276
|
-
end
|
277
|
-
|
278
|
-
context "defined by string type" do
|
279
|
-
it 'returns nil for a class match' do
|
280
|
-
config.excluded_exceptions << 'Sentry::Test::BaseExc'
|
281
|
-
expect(subject.event_from_exception(Sentry::Test::BaseExc.new)).to be_nil
|
282
|
-
end
|
283
|
-
|
284
|
-
it 'returns nil for a top class match' do
|
285
|
-
config.excluded_exceptions << '::Sentry::Test::BaseExc'
|
286
|
-
expect(subject.event_from_exception(Sentry::Test::BaseExc.new)).to be_nil
|
287
|
-
end
|
288
|
-
|
289
|
-
it 'returns nil for a sub class match' do
|
290
|
-
config.excluded_exceptions << 'Sentry::Test::BaseExc'
|
291
|
-
expect(subject.event_from_exception(Sentry::Test::SubExc.new)).to be_nil
|
292
|
-
end
|
293
|
-
|
294
|
-
it 'returns nil for a tagged class match' do
|
295
|
-
config.excluded_exceptions << 'Sentry::Test::ExcTag'
|
296
|
-
expect(
|
297
|
-
subject.event_from_exception(Sentry::Test::SubExc.new.tap { |x| x.extend(Sentry::Test::ExcTag) })
|
298
|
-
).to be_nil
|
299
|
-
end
|
300
|
-
|
301
|
-
it 'returns Sentry::Event for an undefined exception class' do
|
302
|
-
config.excluded_exceptions << 'Sentry::Test::NonExistentExc'
|
303
|
-
expect(subject.event_from_exception(Sentry::Test::BaseExc.new)).to be_a(Sentry::Event)
|
304
|
-
end
|
305
|
-
end
|
306
|
-
|
307
|
-
context "defined by class type" do
|
308
|
-
it 'returns nil for a class match' do
|
309
|
-
config.excluded_exceptions << Sentry::Test::BaseExc
|
310
|
-
expect(subject.event_from_exception(Sentry::Test::BaseExc.new)).to be_nil
|
311
|
-
end
|
312
|
-
|
313
|
-
it 'returns nil for a sub class match' do
|
314
|
-
config.excluded_exceptions << Sentry::Test::BaseExc
|
315
|
-
expect(subject.event_from_exception(Sentry::Test::SubExc.new)).to be_nil
|
316
|
-
end
|
317
|
-
|
318
|
-
it 'returns nil for a tagged class match' do
|
319
|
-
config.excluded_exceptions << Sentry::Test::ExcTag
|
320
|
-
expect(subject.event_from_exception(Sentry::Test::SubExc.new.tap { |x| x.extend(Sentry::Test::ExcTag) })).to be_nil
|
321
|
-
end
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
# Only check causes when they're supported
|
326
|
-
if Exception.new.respond_to? :cause
|
327
|
-
context 'when the exception has a cause' do
|
328
|
-
let(:exception) { build_exception_with_cause }
|
329
|
-
|
330
|
-
it 'captures the cause' do
|
331
|
-
expect(hash[:exception][:values].length).to eq(2)
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
|
-
context 'when the exception has nested causes' do
|
336
|
-
let(:exception) { build_exception_with_two_causes }
|
337
|
-
|
338
|
-
it 'captures nested causes' do
|
339
|
-
expect(hash[:exception][:values].length).to eq(3)
|
340
|
-
end
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
context 'when the exception has a recursive cause' do
|
345
|
-
let(:exception) { build_exception_with_recursive_cause }
|
346
|
-
|
347
|
-
it 'should handle it gracefully' do
|
348
|
-
expect(hash[:exception][:values].length).to eq(1)
|
349
|
-
end
|
350
|
-
end
|
351
|
-
|
352
|
-
if RUBY_PLATFORM == "java"
|
353
|
-
context 'when running under jRuby' do
|
354
|
-
let(:exception) do
|
355
|
-
begin
|
356
|
-
raise java.lang.OutOfMemoryError, "A Java error"
|
357
|
-
rescue Exception => e
|
358
|
-
return e
|
359
|
-
end
|
360
|
-
end
|
361
|
-
|
362
|
-
it 'should have a backtrace' do
|
363
|
-
frames = hash[:exception][:values][0][:stacktrace][:frames]
|
364
|
-
expect(frames.length).not_to eq(0)
|
365
|
-
end
|
366
|
-
end
|
367
|
-
end
|
368
|
-
|
369
|
-
context 'when the exception has a backtrace' do
|
370
|
-
let(:exception) do
|
371
|
-
e = Exception.new(message)
|
372
|
-
allow(e).to receive(:backtrace).and_return [
|
373
|
-
"/path/to/some/file:22:in `function_name'",
|
374
|
-
"/some/other/path:1412:in `other_function'"
|
375
|
-
]
|
376
|
-
e
|
377
|
-
end
|
378
|
-
|
379
|
-
it 'parses the backtrace' do
|
380
|
-
frames = hash[:exception][:values][0][:stacktrace][:frames]
|
381
|
-
expect(frames.length).to eq(2)
|
382
|
-
expect(frames[0][:lineno]).to eq(1412)
|
383
|
-
expect(frames[0][:function]).to eq('other_function')
|
384
|
-
expect(frames[0][:filename]).to eq('/some/other/path')
|
385
|
-
|
386
|
-
expect(frames[1][:lineno]).to eq(22)
|
387
|
-
expect(frames[1][:function]).to eq('function_name')
|
388
|
-
expect(frames[1][:filename]).to eq('/path/to/some/file')
|
389
|
-
end
|
390
|
-
|
391
|
-
context 'with internal backtrace' do
|
392
|
-
let(:exception) do
|
393
|
-
e = Exception.new(message)
|
394
|
-
allow(e).to receive(:backtrace).and_return(["<internal:prelude>:10:in `synchronize'"])
|
395
|
-
e
|
396
|
-
end
|
397
|
-
|
398
|
-
it 'marks filename and in_app correctly' do
|
399
|
-
frames = hash[:exception][:values][0][:stacktrace][:frames]
|
400
|
-
expect(frames[0][:lineno]).to eq(10)
|
401
|
-
expect(frames[0][:function]).to eq("synchronize")
|
402
|
-
expect(frames[0][:filename]).to eq("<internal:prelude>")
|
403
|
-
end
|
404
|
-
end
|
405
|
-
|
406
|
-
context 'when a path in the stack trace is on the load path' do
|
407
|
-
before do
|
408
|
-
$LOAD_PATH << '/some'
|
409
|
-
end
|
410
|
-
|
411
|
-
after do
|
412
|
-
$LOAD_PATH.delete('/some')
|
413
|
-
end
|
414
|
-
|
415
|
-
it 'strips prefixes in the load path from frame filenames' do
|
416
|
-
frames = hash[:exception][:values][0][:stacktrace][:frames]
|
417
|
-
expect(frames[0][:filename]).to eq('other/path')
|
418
|
-
end
|
419
|
-
end
|
420
|
-
end
|
421
|
-
|
422
|
-
context 'merging exception context' do
|
423
|
-
let(:hash) do
|
424
|
-
event = subject.event_from_exception(
|
425
|
-
ExceptionWithContext.new,
|
426
|
-
message: "MSG",
|
427
|
-
extra: {
|
428
|
-
'context_event_key' => 'event_value',
|
429
|
-
'event_key' => 'event_value'
|
430
|
-
}
|
431
|
-
)
|
432
|
-
event.to_hash
|
433
|
-
end
|
434
|
-
|
435
|
-
it 'prioritizes event context over request context' do
|
436
|
-
expect(hash[:extra]['context_event_key']).to eq('event_value')
|
437
|
-
expect(hash[:extra]['context_key']).to eq('context_value')
|
438
|
-
expect(hash[:extra]['event_key']).to eq('event_value')
|
439
|
-
end
|
440
|
-
end
|
441
|
-
end
|
442
|
-
end
|
443
|
-
end
|