2

I'm specifically asking what the issues may be with my try/catch block, which isn't described in the issues linked as "duplicates" to this.

I'm having an issue where I'm trying to catch a StaleElementReferenceException and then look up the element again but for some reason the exception isn't being caught. I have the method below and when I run the test I get a StaleElementReferenceException when this line is executed, value = element.GetAttribute(attributeName);. I assumed (maybe poorly) that adding the check in a try/catch and specifically looking for the exception would allow me to continue trying until selenium is able to find the element again. The issue is for some reason the exception isn't getting caught and the test immediately exits. Oddly, if I change the catch block to just catch the general Exception it works just fine. My concern with that is though I could get in a loop that would never exit. I'm using a page object model to initially initialize the elements.

bool isStale = false;
string value = "";
do
{
    try
    {
        value = element.GetAttribute(attributeName);
        isStale = false;
    }
    catch (StaleElementReferenceException)
    {
        element = driver.FindElement(By.XPath(xPath));
        isStale = true;
    }

} while (isStale == true);
return value;

This is part of the stack trace:

Test failed with error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> OpenQA.Selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document (Session info: chrome=71.0.3578.98) (Driver info: chromedriver=2.43.600210 (68dcf5eebde37173d4027fa8635e332711d2874a),platform=Windows NT 10.0.17134 x86_64) at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse) at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary2 parameters) at OpenQA.Selenium.Remote.RemoteWebElement.Execute(String commandToExecute, Dictionary2 parameters) at OpenQA.Selenium.Remote.RemoteWebElement.GetAttribute(String attributeName)

T.S.
  • 18,195
  • 11
  • 58
  • 78
Ben
  • 43
  • 5
  • 1
    I'm not sure how those other things are duplicates to this other than the fact they discuss the stale element exception. I understand what the stale element is and I'm trying to look up the element again, as is directed in those other posts. The issue I described in this question is the fact my code isn't working as I thought it would, meaning for some reason my exception isn't getting caught so I can try and look the element up again. Do you have any suggestions as to why the stale element exception isn't getting caught by my code? Thanks. – Ben Dec 19 '18 at 13:51
  • 2
    @DebanjanB Neither one of the questions you dup'd this to are relevant. One is python, this is C#. The other is PageFactory related and this has no mention of PageFactory. Undo the dup. – JeffC Dec 19 '18 at 14:21
  • 1
    I'm not sure why your code isn't working. One guess is that the exception is thrown *inside* your `catch` statement. The better way to handle stale elements is to deal with what is causing the page/elements to refresh. Wait for the page/element refresh to complete and then pull the attribute. – JeffC Dec 19 '18 at 14:30
  • One way you can rewrite/simplify this code is to do something like: `do { try { return driver.FindElement(By.XPath(xPath)).GetAttribute(attributeName); } catch (StaleElementReferenceException) { Thread.Sleep(500); } } while (true);` – JeffC Dec 19 '18 at 14:31
  • Basically you return when you get the value instead of tracking `isStale` and just refetch the element instead of testing it the first time. The `Thread.Sleep()` is just a brief pause between attempts. Once the exception isn't thrown, it will exit the `do` loop via `return` – JeffC Dec 19 '18 at 14:33
  • Thanks @JeffC. I appreciate the suggestion on how to simplify my logic. I agree that is much cleaner. I'll also continue my research into the exact action causing the elements to be rebuilt so I can try and better handle the scenario throwing the exception. – Ben Dec 19 '18 at 15:59
  • @Andersson Can you undup this? – JeffC Dec 19 '18 at 16:32
  • @DebanjanB This is not a duplicate – T.S. Dec 19 '18 at 17:14
  • Your problem is that you execute more code that can give exception in your exception handling and add `catch TargetInvocationException` – T.S. Dec 19 '18 at 17:15
  • *I'm using a page object model to initially initialize the elements* do you mean `PageFactory`? can you post this code as well? – Guy Dec 20 '18 at 10:09
  • @T.S. Thanks for the response. When you say, "and add catch TargetInvocationException" what do you mean? I know there is logic in my catch block but my intent was to basically try and look up the element again until it wasn't stale. I was unaware the FindElement method would return a stale element exception. I understand it can return an element not found, which is fine because then I would expect the failure.That's just not the one I was getting. The test was still failing with the stale element exception, even though I thought I was catching it correctly. – Ben Dec 20 '18 at 12:12
  • @Guy. Sorry, that last statement doesn't really pertain to this specific example and I shouldn't have added it. I do have some pages using page factory but in this specific case the element in question is not initialized there. I'm looking it up on the fly as I'm modifying the xpath based on a row number of the exact field I want. – Ben Dec 20 '18 at 12:23
  • @Ben I see. Anyway, unexplained behavior sometimes solved by upgrading. Try updating Selenium and `ChromeDriver` to the latest versions. – Guy Dec 20 '18 at 12:27
  • @Guy thanks. i did notice yesterday i was 2 versions behind on my chromedriver so I'll give that a shot. – Ben Dec 20 '18 at 12:39
  • I mean, you can have many `catch` - `catch (exception1){ } catch (exception2){ } `. The last one should be base `Exception` – T.S. Dec 20 '18 at 14:58
  • @DebanjanB thank you sir – T.S. Dec 20 '18 at 14:58

0 Answers0