Open aguspe opened 1 week ago
โฑ๏ธ Estimated effort to review [1-5] | 2 |
๐งช Relevant tests | Yes |
๐ Security concerns | No |
โก Key issues to review |
Thread Safety: The method backtrace_locations uses Thread.current.backtrace_locations which is thread-specific. Ensure that this usage is safe in the context of how the WebDriverError class is utilized across different threads. |
Error Handling: The cause method returns $ERROR_INFO , which is a global variable provided by the 'English' library for the last raised exception. Confirm that this approach correctly captures the intended exceptions in all scenarios. |
Category | Suggestion | Score |
Best practice |
Use
___
**Instead of using | 8 |
Enhancement |
Ensure
___
**Add a check to ensure that | 7 |
Ensure the
___
**Improve the test for the | 6 | |
Possible issue |
Add a guard clause to handle nil values in
___
**Add a guard clause to | 7 |
I resolved the conflicts after the merge of #14174 and updated the error class, all the tests seem to be working, could I get a review? @p0deje
I am not sure I follow the implementation and how it works. What we discussed in #13222 was to stop manipulating backtrace, create a nextra error instance and explicitly pass
cause
for errors created from the remote server in. Does this PR achieve the same in some other manner?
Oh Maybe I miss understood this, because I tried to call both backtrace_locations and case on the ex, and I noticed I couldn't so I implemented the methods that are being inherited from exception, so now when creating an error both the case and backtrace_locations are set automatically
So for example this test:
it 'has cause' do
driver.find_element(id: 'nonexistent')
rescue WebDriver::Error::NoSuchElementError => e
expect(e.cause).to be_a(WebDriver::Error::NoSuchElementError)
end
returns cause as:
#<Selenium::WebDriver::Error::NoSuchElementError: no such element: Unable to locate element: {"method":"css selector","selector":"#nonexistent"}
(Session info: chrome=126.0.6478.116); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception>
And this test :
it 'has backtrace locations' do
driver.find_element(id: 'nonexistent')
rescue WebDriver::Error::NoSuchElementError => e
expect(e.backtrace_locations).not_to be_empty
end
Returns backtrace locations as:
["/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/common/error.rb:57:in `backtrace_locations'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/common/error.rb:57:in `backtrace_locations'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/spec/integration/selenium/webdriver/error_spec.rb:36:in `rescue in block (2 levels) in <module:WebDriver>'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/spec/integration/selenium/webdriver/error_spec.rb:34:in `block (2 levels) in <module:WebDriver>'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263:in `instance_exec'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263:in `block in run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:511:in `block in with_around_and_singleton_context_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:468:in `block in with_around_example_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:486:in `block in run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:626:in `block in run_around_example_hooks_for'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:352:in `call'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/expectations/failure_aggregator.rb:25:in `block in aggregate'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-support-3.13.1/lib/rspec/support.rb:126:in `with_failure_notifier'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/expectations/failure_aggregator.rb:23:in `aggregate'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/matchers.rb:306:in `aggregate_failures'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/configuration.rb:2281:in `block in define_built_in_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:457:in `instance_exec'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:457:in `instance_exec'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:390:in `execute_with'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:628:in `block (2 levels) in run_around_example_hooks_for'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:352:in `call'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:629:in `run_around_example_hooks_for'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:486:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:468:in `with_around_example_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:511:in `with_around_and_singleton_context_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:259:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:646:in `block in run_examples'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:642:in `map'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:642:in `run_examples'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:607:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `block (3 levels) in run_specs'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `map'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `block (2 levels) in run_specs'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/configuration.rb:2091:in `with_suite_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:116:in `block in run_specs'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/reporter.rb:74:in `report'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:115:in `run_specs'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:89:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:71:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:45:in `invoke'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/exe/rspec:4:in `<top (required)>'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/bin/rspec:25:in `load'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/bin/rspec:25:in `<main>'"]
Also these are the methods from the exception class that I'm overriding, that returns nil even if the backtrace is not set:
# This method is not affected by Exception#set_backtrace().
def backtrace_locations; end
# Returns the previous exception ($!) at the time this exception was raised.
# This is useful for wrapping exceptions and retaining the original exception
# information.
def cause; end
@p0deje I see what you are saying and I updated the implementation by removing the backtrace manipulation, and the test kept working, now I will update the cause, thank you! it's my first time working with exceptions so sorry for the confusion
@aguspe I think we're a bit misaligned on what needs to be done. Let me try to explain the current implementation:
Now, what we want to do is to replace implementation in 2:
WebDriverError
with a message and a stacktrace from the server.cause
of the original error.Roughly, it would look like this in response.rb
def error
error, message, backtrace = process_error
klass = Error.for_error(error) || return
ex = klass.new(message)
if backtrace
cause = WebDriverError.new(message)
add_backtrace(cause, backtrace)
ex.cause = cause
end
ex
end
@aguspe I think we're a bit misaligned on what needs to be done. Let me try to explain the current implementation:
- When Selenium::WebDriver is used with a local driver (e.g. chromedriver) and it raises an exception, it's returned as-is.
- When it's used with a remote driver (e.g. Grid + chromedriver), the Grid provides extra information about the error (e.g. Grid server logs). This information is then appended to a backtrace of an original error.
Now, what we want to do is to replace implementation in 2:
- Don't change the backtrace of the original error.
- Create one more
WebDriverError
with a message and a stacktrace from the server.- Make it
cause
of the original error.Roughly, it would look like this in response.rb
def error error, message, backtrace = process_error klass = Error.for_error(error) || return ex = klass.new(message) if backtrace cause = WebDriverError.new(message) add_backtrace(cause, backtrace) ex.cause = cause end ex end
Thank you so much for the explanation @p0deje,
The only way I found on how to get the backtrace, the backtrace_locations and the cause was the last implementation I did, So I had to raise the cause, and rescue it, and then raise the expected exception and rescue it to get the cause set,
With the backtrace I had this odd issue if I used the method set_backtrace that shouldn't affect the backtrace_locations, it always made the backtrace_locations to be nil
If I only raise the cause error, the cause was also always nil
I remove again the backtrace method because again, if I set the backtrace after parsing it I lost the backtrace_locations, I hope this makes sense, and thank you one more time for all the help
Edit:
A quick update @p0deje, I found a way to make it work by setting the backtrace at the end after adding the cause and then returning the exception, so I think with the last commit this is the best solution to fix this bug
I hope on my last comment here the implementation makes more sense and achieve what the goal is, I couldn't add the backtrace to the cause but the backtrace is still there and also the backtrace locations, so let me know if this is closer to what is expected
thank you so much for the help!
@p0deje @ioquatix
Then my recommendation would be keeping the latest implementation with:
Cause as:
pp e.cause
Selenium::WebDriver::Error::WebDriverError
Backtrace as:
pp e.backtrace
["/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:62:in `rescue in add_cause'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:59:in `add_cause'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:41:in `error'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:52:in `assert_ok'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:34:in `initialize'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/common.rb:101:in `new'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/common.rb:101:in `create_response'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/default.rb:103:in `request'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/common.rb:67:in `call'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/bridge.rb:675:in `execute'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/bridge.rb:543:in `find_element_by'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/common/search_context.rb:71:in `find_element'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/spec/integration/selenium/webdriver/error_spec.rb:48:in `block (2 levels) in <module:WebDriver>'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263:in `instance_exec'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263:in `block in run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:511:in `block in with_around_and_singleton_context_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:468:in `block in with_around_example_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:486:in `block in run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:626:in `block in run_around_example_hooks_for'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:352:in `call'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/expectations/failure_aggregator.rb:25:in `block in aggregate'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-support-3.13.1/lib/rspec/support.rb:126:in `with_failure_notifier'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/expectations/failure_aggregator.rb:23:in `aggregate'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/matchers.rb:306:in `aggregate_failures'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/configuration.rb:2281:in `block in define_built_in_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:457:in `instance_exec'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:457:in `instance_exec'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:390:in `execute_with'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:628:in `block (2 levels) in run_around_example_hooks_for'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:352:in `call'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:629:in `run_around_example_hooks_for'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:486:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:468:in `with_around_example_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:511:in `with_around_and_singleton_context_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:259:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:646:in `block in run_examples'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:642:in `map'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:642:in `run_examples'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:607:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `block (3 levels) in run_specs'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `map'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `block (2 levels) in run_specs'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/configuration.rb:2091:in `with_suite_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:116:in `block in run_specs'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/reporter.rb:74:in `report'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:115:in `run_specs'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:89:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:71:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:45:in `invoke'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/exe/rspec:4:in `<top (required)>'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/bin/rspec:25:in `load'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/bin/rspec:25:in `<main>'"]
Backtrace locations as:
pp e.backtrace_locations
["/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:62:in `rescue in add_cause'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:59:in `add_cause'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:41:in `error'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:52:in `assert_ok'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/response.rb:34:in `initialize'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/common.rb:101:in `new'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/common.rb:101:in `create_response'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/default.rb:103:in `request'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/http/common.rb:67:in `call'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/bridge.rb:675:in `execute'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/remote/bridge.rb:543:in `find_element_by'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/lib/selenium/webdriver/common/search_context.rb:71:in `find_element'",
"/Users/apeque01/Desktop/main_folder/Projects/open_source/selenium/rb/spec/integration/selenium/webdriver/error_spec.rb:34:in `block (2 levels) in <module:WebDriver>'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263:in `instance_exec'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:263:in `block in run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:511:in `block in with_around_and_singleton_context_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:468:in `block in with_around_example_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:486:in `block in run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:626:in `block in run_around_example_hooks_for'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:352:in `call'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/expectations/failure_aggregator.rb:25:in `block in aggregate'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-support-3.13.1/lib/rspec/support.rb:126:in `with_failure_notifier'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/expectations/failure_aggregator.rb:23:in `aggregate'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-expectations-3.13.1/lib/rspec/matchers.rb:306:in `aggregate_failures'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/configuration.rb:2281:in `block in define_built_in_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:457:in `instance_exec'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:457:in `instance_exec'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:390:in `execute_with'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:628:in `block (2 levels) in run_around_example_hooks_for'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:352:in `call'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:629:in `run_around_example_hooks_for'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/hooks.rb:486:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:468:in `with_around_example_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:511:in `with_around_and_singleton_context_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example.rb:259:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:646:in `block in run_examples'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:642:in `map'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:642:in `run_examples'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/example_group.rb:607:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `block (3 levels) in run_specs'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `map'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:121:in `block (2 levels) in run_specs'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/configuration.rb:2091:in `with_suite_hooks'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:116:in `block in run_specs'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/reporter.rb:74:in `report'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:115:in `run_specs'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:89:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:71:in `run'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/lib/rspec/core/runner.rb:45:in `invoke'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/gems/rspec-core-3.13.0/exe/rspec:4:in `<top (required)>'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/bin/rspec:25:in `load'",
"/Users/apeque01/.rvm/gems/ruby-3.0.0/bin/rspec:25:in `<main>'"]
Thanks for the quick review now cause includes the backtrace @p0deje
pp e.cause
#<Selenium::WebDriver::Error::WebDriverError: 0 chromedriver 0x00000001006f6a80 chromedriver + 4385408
1 chromedriver 0x00000001006ef38c chromedriver + 4354956
2 chromedriver 0x000000010030cb0c chromedriver + 281356
3 chromedriver 0x000000010034f2f8 chromedriver + 553720
4 chromedriver 0x0000000100387d24 chromedriver + 785700
5 chromedriver 0x0000000100343eec chromedriver + 507628
6 chromedriver 0x00000001003448c4 chromedriver + 510148
7 chromedriver 0x00000001006be43c chromedriver + 4154428
8 chromedriver 0x00000001006c2ea0 chromedriver + 4173472
9 chromedriver 0x00000001006a3ff8 chromedriver + 4046840
10 chromedriver 0x00000001006c378c chromedriver + 4175756
11 chromedriver 0x0000000100696fb8 chromedriver + 3993528
12 chromedriver 0x00000001006e121c chromedriver + 4297244
13 chromedriver 0x00000001006e1398 chromedriver + 4297624
14 chromedriver 0x00000001006eef84 chromedriver + 4353924
15 libsystem_pthread.dylib 0x00000001940cef94 _pthread_start + 136
16 libsystem_pthread.dylib 0x00000001940c9d34 thread_start + 8
>
User description
Description
The goal of this PR is to provide backtrace_locations and cause for users that need to consume it
Motivation and Context
A great detail explanation of the motivation is described here #13221 and also more information is provided in #13222
Types of changes
Checklist
PR Type
Enhancement, Tests
Description
WebDriverError
class by addingbacktrace_locations
method to fetch current thread's backtrace locations.WebDriverError
class by addingcause
method to fetch the error information.English
module for improved error handling.NoSuchElementError
.Changes walkthrough ๐
error.rb
Add backtrace locations and cause methods to WebDriverError class
rb/lib/selenium/webdriver/common/error.rb
backtrace_locations
method toWebDriverError
class to fetchcurrent thread's backtrace locations.
cause
method toWebDriverError
class to fetch the errorinformation.
English
module for error handling.error_spec.rb
Add tests for backtrace locations and cause in NoSuchElementError
rb/spec/integration/selenium/webdriver/error_spec.rb
NoSuchElementError
.NoSuchElementError
.