1

I have this code below:

def test_counter(self):
    try:
        if self.driver.find_element_by_id(self.counter).text == 'texttexttext':
            return True
    except NoSuchElementException and StaleElementReferenceException:
        self.fix_error()
    return False

And I cannot figure out why the NoSuchElementException or the StaleElementReferenceException are not being caught.

Remi Guan
  • 21,506
  • 17
  • 64
  • 87
Aleksai Losey
  • 60
  • 2
  • 7

2 Answers2

7

Change this line:

except NoSuchElementException and StaleElementReferenceException:

into:

except (NoSuchElementException, StaleElementReferenceException):

This is the reason:

>>> NoSuchElementException and StaleElementReferenceException
StaleElementReferenceException

The and checks if NoSuchElementException is true first. Since this is case, it checks if StaleElementReferenceException is true. Because it also true, it returns this class.

Use pylint and it will warn you about this:

Exception to catch is the result of a binary "and" operation (binary-op-exception)
Mike Müller
  • 82,630
  • 20
  • 166
  • 161
6

A and B become B if both A and B is truth values. So NoSuchElementException and StaleElementReferenceException become StaleElementReferenceException; The code is catching that exception only.

>>> NoSuchElementException and StaleElementReferenceException
<class 'selenium.common.exceptions.StaleElementReferenceException'>

You need to use except (NoSuchElementException, StaleElementReferenceException): to catch both exceptions.

falsetru
  • 357,413
  • 63
  • 732
  • 636
  • Hmm...`from foobar import *` isn't recommended. – Remi Guan Dec 10 '15 at 01:48
  • @KevinGuan: For a well namedspaced package, assuming it really only includes the `selenium` specific exceptions, it's not so bad. It's annoying to need to qualify all the exceptions you might have to handle, or import them all explicitly by name. – ShadowRanger Dec 10 '15 at 01:49
  • Side-note: If you need to catch the exception and store it, you'd use `except (NoSuchElementException, StaleElementReferenceException) as somename:` (where `somename` is usually just `e`, but I wanted to make it clear the name is whatever you choose). – ShadowRanger Dec 10 '15 at 01:50
  • @KevinGuan, I did it for brevity. – falsetru Dec 10 '15 at 01:51
  • @ShadowRanger: Ah, yep. But however I'd prefer always use `from foo import bar` if you don't need all things in `foo`. That would be clear than `*`. – Remi Guan Dec 10 '15 at 01:53
  • 1
    @KevinGuan, I removed the import line because it's not a point of the answer. Thank you for your feedback. – falsetru Dec 10 '15 at 04:09