Skip to content

Commit d883028

Browse files
authored
[rb] Add backtrace locations and cause to errors (#14170)
Co-authored-by: aguspe <[email protected]>
1 parent 4a17ec3 commit d883028

File tree

5 files changed

+34
-49
lines changed

5 files changed

+34
-49
lines changed

rb/lib/selenium/webdriver/common/error.rb

+1-5
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,7 @@ class UnknownCommandError < WebDriverError; end
7777
# A command failed because the referenced element is no longer attached to the DOM.
7878
#
7979

80-
class StaleElementReferenceError < WebDriverError
81-
def initialize(msg = '')
82-
super("#{msg}; #{SUPPORT_MSG} #{URLS[:StaleElementReferenceError]}")
83-
end
84-
end
80+
class StaleElementReferenceError < WebDriverError; end
8581

8682
#
8783
# A command failed because the referenced shadow root is no longer attached to the DOM.

rb/lib/selenium/webdriver/remote/response.rb

+8-33
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class Response
2828
attr_reader :code, :payload
2929

3030
def initialize(code, payload = nil)
31-
@code = code
31+
@code = code
3232
@payload = payload || {}
3333

3434
assert_ok
@@ -37,11 +37,8 @@ def initialize(code, payload = nil)
3737
def error
3838
error, message, backtrace = process_error
3939
klass = Error.for_error(error) || return
40-
4140
ex = klass.new(message)
42-
ex.set_backtrace(caller)
43-
add_backtrace ex, backtrace
44-
41+
add_cause(ex, error, backtrace)
4542
ex
4643
end
4744

@@ -59,34 +56,12 @@ def assert_ok
5956
raise Error::ServerError, self
6057
end
6158

62-
def add_backtrace(ex, server_trace)
63-
return unless server_trace
64-
65-
backtrace = case server_trace
66-
when Array
67-
backtrace_from_remote(server_trace)
68-
when String
69-
server_trace.split("\n")
70-
end
71-
72-
ex.set_backtrace(backtrace + ex.backtrace)
73-
end
74-
75-
def backtrace_from_remote(server_trace)
76-
server_trace.filter_map do |frame|
77-
next unless frame.is_a?(Hash)
78-
79-
file = frame['fileName']
80-
line = frame['lineNumber']
81-
meth = frame['methodName']
82-
83-
class_name = frame['className']
84-
file = "#{class_name}(#{file})" if class_name
85-
86-
meth = 'unknown' if meth.nil? || meth.empty?
87-
88-
"[remote server] #{file}:#{line}:in `#{meth}'"
89-
end
59+
def add_cause(ex, error, backtrace)
60+
cause = Error::WebDriverError.new
61+
cause.set_backtrace(backtrace)
62+
raise ex, cause: cause
63+
rescue Error.for_error(error)
64+
ex
9065
end
9166

9267
def process_error

rb/sig/lib/selenium/webdriver/common/error.rbs

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module Selenium
22
module WebDriver
33
module Error
4-
def self.for_error: (untyped error) -> untyped
4+
def self.for_error: (String? error) -> Class?
55

66
SUPPORT_MSG: String
77

@@ -10,11 +10,12 @@ module Selenium
1010
URLS: Hash[Symbol, String]
1111

1212
class WebDriverError < StandardError
13+
def initialize: (?String | Array[String] msg) -> void
14+
1315
def class_name: -> Symbol?
1416
end
1517

1618
class NoSuchElementError < WebDriverError
17-
def initialize: (?String msg) -> void
1819
end
1920

2021
class NoSuchFrameError < WebDriverError
@@ -24,7 +25,6 @@ module Selenium
2425
end
2526

2627
class StaleElementReferenceError < WebDriverError
27-
def initialize: (?String msg) -> void
2828
end
2929

3030
class DetachedShadowRootError < WebDriverError
@@ -61,7 +61,6 @@ module Selenium
6161
end
6262

6363
class InvalidSelectorError < WebDriverError
64-
def initialize: (?::String msg) -> void
6564
end
6665

6766
class SessionNotCreatedError < WebDriverError
@@ -101,7 +100,6 @@ module Selenium
101100
end
102101

103102
class NoSuchDriverError < WebDriverError
104-
def initialize: (?String msg) -> void
105103
end
106104
end
107105
end

rb/sig/lib/selenium/webdriver/remote/response.rbs

+4-6
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,17 @@ module Selenium
1212

1313
def initialize: (String code, ?Hash[untyped, untyped]? payload) -> void
1414

15-
def error: () -> (nil | untyped)
15+
def error: () -> Error::WebDriverError?
1616

1717
def []: (untyped key) -> untyped
1818

1919
private
2020

21-
def assert_ok: () -> (nil | untyped)
21+
def assert_ok: () -> Error::WebDriverError
2222

23-
def add_backtrace: (untyped ex, untyped server_trace) -> (nil | untyped)
23+
def add_cause: (Error::WebDriverError ex, String error, Array[String] backtrace) -> Error::WebDriverError
2424

25-
def backtrace_from_remote: (untyped server_trace) -> String
26-
27-
def process_error: () -> (nil | untyped)
25+
def process_error: () -> Array[Hash[untyped, untyped]]
2826
end
2927
end
3028
end

rb/spec/integration/selenium/webdriver/error_spec.rb

+18
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,24 @@ module WebDriver
2929
driver.find_element(id: 'nonexistent')
3030
}.to raise_error(WebDriver::Error::NoSuchElementError, /#no-such-element-exception/)
3131
end
32+
33+
it 'has backtrace locations' do
34+
driver.find_element(id: 'nonexistent')
35+
rescue WebDriver::Error::NoSuchElementError => e
36+
expect(e.backtrace_locations).not_to be_empty
37+
end
38+
39+
it 'has cause' do
40+
driver.find_element(id: 'nonexistent')
41+
rescue WebDriver::Error::NoSuchElementError => e
42+
expect(e.cause).to be_a(WebDriver::Error::WebDriverError)
43+
end
44+
45+
it 'has backtrace' do
46+
driver.find_element(id: 'nonexistent')
47+
rescue WebDriver::Error::NoSuchElementError => e
48+
expect(e.backtrace).not_to be_empty
49+
end
3250
end
3351
end # WebDriver
3452
end # Selenium

0 commit comments

Comments
 (0)