sentry-raven 3.1.1 → 3.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (163) hide show
  1. checksums.yaml +4 -4
  2. data/.craft.yml +9 -5
  3. data/.scripts/bump-version.rb +5 -0
  4. data/CHANGELOG.md +11 -0
  5. data/Gemfile +5 -1
  6. data/Makefile +3 -0
  7. data/README.md +19 -7
  8. data/lib/raven/base.rb +1 -0
  9. data/lib/raven/configuration.rb +0 -1
  10. data/lib/raven/event.rb +5 -1
  11. data/lib/raven/instance.rb +7 -1
  12. data/lib/raven/integrations/delayed_job.rb +1 -1
  13. data/lib/raven/integrations/rack.rb +2 -14
  14. data/lib/raven/transports/http.rb +2 -1
  15. data/lib/raven/utils/request_id.rb +16 -0
  16. data/lib/raven/version.rb +1 -1
  17. data/sentry-raven.gemspec +7 -0
  18. metadata +10 -148
  19. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -32
  20. data/.github/pull_request_template.md +0 -16
  21. data/.github/workflows/test.yml +0 -92
  22. data/.github/workflows/zeus_upload.yml +0 -32
  23. data/.gitignore +0 -16
  24. data/.gitmodules +0 -0
  25. data/.rspec +0 -1
  26. data/.rubocop.yml +0 -112
  27. data/.scripts/bump-version.sh +0 -9
  28. data/CONTRIBUTING.md +0 -71
  29. data/sentry-ruby/.gitignore +0 -11
  30. data/sentry-ruby/.rspec +0 -3
  31. data/sentry-ruby/.travis.yml +0 -6
  32. data/sentry-ruby/CODE_OF_CONDUCT.md +0 -74
  33. data/sentry-ruby/Gemfile +0 -9
  34. data/sentry-ruby/LICENSE.txt +0 -21
  35. data/sentry-ruby/README.md +0 -44
  36. data/sentry-ruby/Rakefile +0 -6
  37. data/sentry-ruby/bin/console +0 -14
  38. data/sentry-ruby/bin/setup +0 -8
  39. data/sentry-ruby/examples/rails-6.0/.browserslistrc +0 -1
  40. data/sentry-ruby/examples/rails-6.0/.gitignore +0 -35
  41. data/sentry-ruby/examples/rails-6.0/Gemfile +0 -58
  42. data/sentry-ruby/examples/rails-6.0/README.md +0 -23
  43. data/sentry-ruby/examples/rails-6.0/Rakefile +0 -6
  44. data/sentry-ruby/examples/rails-6.0/app/assets/config/manifest.js +0 -2
  45. data/sentry-ruby/examples/rails-6.0/app/assets/images/.keep +0 -0
  46. data/sentry-ruby/examples/rails-6.0/app/assets/stylesheets/application.css +0 -15
  47. data/sentry-ruby/examples/rails-6.0/app/channels/application_cable/channel.rb +0 -4
  48. data/sentry-ruby/examples/rails-6.0/app/channels/application_cable/connection.rb +0 -4
  49. data/sentry-ruby/examples/rails-6.0/app/controllers/application_controller.rb +0 -2
  50. data/sentry-ruby/examples/rails-6.0/app/controllers/concerns/.keep +0 -0
  51. data/sentry-ruby/examples/rails-6.0/app/controllers/welcome_controller.rb +0 -23
  52. data/sentry-ruby/examples/rails-6.0/app/helpers/application_helper.rb +0 -2
  53. data/sentry-ruby/examples/rails-6.0/app/javascript/channels/consumer.js +0 -6
  54. data/sentry-ruby/examples/rails-6.0/app/javascript/channels/index.js +0 -5
  55. data/sentry-ruby/examples/rails-6.0/app/javascript/packs/application.js +0 -17
  56. data/sentry-ruby/examples/rails-6.0/app/jobs/application_job.rb +0 -7
  57. data/sentry-ruby/examples/rails-6.0/app/mailers/application_mailer.rb +0 -4
  58. data/sentry-ruby/examples/rails-6.0/app/models/application_record.rb +0 -3
  59. data/sentry-ruby/examples/rails-6.0/app/models/concerns/.keep +0 -0
  60. data/sentry-ruby/examples/rails-6.0/app/views/layouts/application.html.erb +0 -15
  61. data/sentry-ruby/examples/rails-6.0/app/views/layouts/mailer.html.erb +0 -13
  62. data/sentry-ruby/examples/rails-6.0/app/views/layouts/mailer.text.erb +0 -1
  63. data/sentry-ruby/examples/rails-6.0/app/views/welcome/report_demo.html.erb +0 -22
  64. data/sentry-ruby/examples/rails-6.0/app/views/welcome/view_error.html.erb +0 -1
  65. data/sentry-ruby/examples/rails-6.0/app/workers/error_worker.rb +0 -7
  66. data/sentry-ruby/examples/rails-6.0/babel.config.js +0 -72
  67. data/sentry-ruby/examples/rails-6.0/bin/bundle +0 -114
  68. data/sentry-ruby/examples/rails-6.0/bin/rails +0 -9
  69. data/sentry-ruby/examples/rails-6.0/bin/rake +0 -9
  70. data/sentry-ruby/examples/rails-6.0/bin/setup +0 -36
  71. data/sentry-ruby/examples/rails-6.0/bin/spring +0 -17
  72. data/sentry-ruby/examples/rails-6.0/bin/webpack +0 -18
  73. data/sentry-ruby/examples/rails-6.0/bin/webpack-dev-server +0 -18
  74. data/sentry-ruby/examples/rails-6.0/bin/yarn +0 -11
  75. data/sentry-ruby/examples/rails-6.0/config.ru +0 -5
  76. data/sentry-ruby/examples/rails-6.0/config/application.rb +0 -28
  77. data/sentry-ruby/examples/rails-6.0/config/boot.rb +0 -4
  78. data/sentry-ruby/examples/rails-6.0/config/cable.yml +0 -10
  79. data/sentry-ruby/examples/rails-6.0/config/credentials.yml.enc +0 -1
  80. data/sentry-ruby/examples/rails-6.0/config/database.yml +0 -25
  81. data/sentry-ruby/examples/rails-6.0/config/environment.rb +0 -5
  82. data/sentry-ruby/examples/rails-6.0/config/environments/development.rb +0 -62
  83. data/sentry-ruby/examples/rails-6.0/config/environments/production.rb +0 -112
  84. data/sentry-ruby/examples/rails-6.0/config/environments/test.rb +0 -48
  85. data/sentry-ruby/examples/rails-6.0/config/initializers/application_controller_renderer.rb +0 -8
  86. data/sentry-ruby/examples/rails-6.0/config/initializers/assets.rb +0 -14
  87. data/sentry-ruby/examples/rails-6.0/config/initializers/backtrace_silencers.rb +0 -7
  88. data/sentry-ruby/examples/rails-6.0/config/initializers/content_security_policy.rb +0 -30
  89. data/sentry-ruby/examples/rails-6.0/config/initializers/cookies_serializer.rb +0 -5
  90. data/sentry-ruby/examples/rails-6.0/config/initializers/filter_parameter_logging.rb +0 -4
  91. data/sentry-ruby/examples/rails-6.0/config/initializers/inflections.rb +0 -16
  92. data/sentry-ruby/examples/rails-6.0/config/initializers/mime_types.rb +0 -4
  93. data/sentry-ruby/examples/rails-6.0/config/initializers/wrap_parameters.rb +0 -14
  94. data/sentry-ruby/examples/rails-6.0/config/locales/en.yml +0 -33
  95. data/sentry-ruby/examples/rails-6.0/config/puma.rb +0 -38
  96. data/sentry-ruby/examples/rails-6.0/config/routes.rb +0 -10
  97. data/sentry-ruby/examples/rails-6.0/config/spring.rb +0 -6
  98. data/sentry-ruby/examples/rails-6.0/config/storage.yml +0 -34
  99. data/sentry-ruby/examples/rails-6.0/config/webpack/development.js +0 -5
  100. data/sentry-ruby/examples/rails-6.0/config/webpack/environment.js +0 -3
  101. data/sentry-ruby/examples/rails-6.0/config/webpack/production.js +0 -5
  102. data/sentry-ruby/examples/rails-6.0/config/webpack/test.js +0 -5
  103. data/sentry-ruby/examples/rails-6.0/config/webpacker.yml +0 -96
  104. data/sentry-ruby/examples/rails-6.0/db/seeds.rb +0 -7
  105. data/sentry-ruby/examples/rails-6.0/lib/assets/.keep +0 -0
  106. data/sentry-ruby/examples/rails-6.0/lib/tasks/.keep +0 -0
  107. data/sentry-ruby/examples/rails-6.0/package.json +0 -15
  108. data/sentry-ruby/examples/rails-6.0/postcss.config.js +0 -12
  109. data/sentry-ruby/examples/rails-6.0/public/404.html +0 -67
  110. data/sentry-ruby/examples/rails-6.0/public/422.html +0 -67
  111. data/sentry-ruby/examples/rails-6.0/public/500.html +0 -66
  112. data/sentry-ruby/examples/rails-6.0/public/apple-touch-icon-precomposed.png +0 -0
  113. data/sentry-ruby/examples/rails-6.0/public/apple-touch-icon.png +0 -0
  114. data/sentry-ruby/examples/rails-6.0/public/favicon.ico +0 -0
  115. data/sentry-ruby/examples/rails-6.0/public/robots.txt +0 -1
  116. data/sentry-ruby/examples/rails-6.0/storage/.keep +0 -0
  117. data/sentry-ruby/examples/rails-6.0/test/application_system_test_case.rb +0 -5
  118. data/sentry-ruby/examples/rails-6.0/test/channels/application_cable/connection_test.rb +0 -11
  119. data/sentry-ruby/examples/rails-6.0/test/controllers/.keep +0 -0
  120. data/sentry-ruby/examples/rails-6.0/test/fixtures/.keep +0 -0
  121. data/sentry-ruby/examples/rails-6.0/test/fixtures/files/.keep +0 -0
  122. data/sentry-ruby/examples/rails-6.0/test/helpers/.keep +0 -0
  123. data/sentry-ruby/examples/rails-6.0/test/integration/.keep +0 -0
  124. data/sentry-ruby/examples/rails-6.0/test/mailers/.keep +0 -0
  125. data/sentry-ruby/examples/rails-6.0/test/models/.keep +0 -0
  126. data/sentry-ruby/examples/rails-6.0/test/system/.keep +0 -0
  127. data/sentry-ruby/examples/rails-6.0/test/test_helper.rb +0 -13
  128. data/sentry-ruby/examples/rails-6.0/vendor/.keep +0 -0
  129. data/sentry-ruby/examples/rails-6.0/yarn.lock +0 -7508
  130. data/sentry-ruby/lib/sentry.rb +0 -16
  131. data/sentry-ruby/lib/sentry/backtrace.rb +0 -128
  132. data/sentry-ruby/lib/sentry/client.rb +0 -162
  133. data/sentry-ruby/lib/sentry/client/state.rb +0 -40
  134. data/sentry-ruby/lib/sentry/configuration.rb +0 -533
  135. data/sentry-ruby/lib/sentry/event.rb +0 -209
  136. data/sentry-ruby/lib/sentry/interface.rb +0 -31
  137. data/sentry-ruby/lib/sentry/interfaces/exception.rb +0 -15
  138. data/sentry-ruby/lib/sentry/interfaces/http.rb +0 -16
  139. data/sentry-ruby/lib/sentry/interfaces/message.rb +0 -18
  140. data/sentry-ruby/lib/sentry/interfaces/single_exception.rb +0 -14
  141. data/sentry-ruby/lib/sentry/interfaces/stack_trace.rb +0 -69
  142. data/sentry-ruby/lib/sentry/linecache.rb +0 -44
  143. data/sentry-ruby/lib/sentry/logger.rb +0 -20
  144. data/sentry-ruby/lib/sentry/transports.rb +0 -19
  145. data/sentry-ruby/lib/sentry/transports/dummy.rb +0 -16
  146. data/sentry-ruby/lib/sentry/transports/http.rb +0 -66
  147. data/sentry-ruby/lib/sentry/transports/stdout.rb +0 -20
  148. data/sentry-ruby/lib/sentry/utils/deep_merge.rb +0 -22
  149. data/sentry-ruby/lib/sentry/utils/exception_cause_chain.rb +0 -20
  150. data/sentry-ruby/lib/sentry/version.rb +0 -3
  151. data/sentry-ruby/sentry-ruby.gemspec +0 -26
  152. data/sentry-ruby/spec/sentry/backtrace_spec.rb +0 -38
  153. data/sentry-ruby/spec/sentry/client_spec.rb +0 -443
  154. data/sentry-ruby/spec/sentry/configuration_spec.rb +0 -400
  155. data/sentry-ruby/spec/sentry/event_spec.rb +0 -238
  156. data/sentry-ruby/spec/sentry/interface_spec.rb +0 -38
  157. data/sentry-ruby/spec/sentry/interfaces/stack_trace_spec.rb +0 -11
  158. data/sentry-ruby/spec/sentry/linecache_spec.rb +0 -40
  159. data/sentry-ruby/spec/sentry/transports/http_spec.rb +0 -57
  160. data/sentry-ruby/spec/sentry/transports/stdout_spec.rb +0 -11
  161. data/sentry-ruby/spec/sentry_spec.rb +0 -9
  162. data/sentry-ruby/spec/spec_helper.rb +0 -49
  163. 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,3 +0,0 @@
1
- module Sentry
2
- VERSION = "0.1.0"
3
- 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