cancel
Showing results for 
Search instead for 
Did you mean: 

Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.

Python driver initial error not catchable?

Should this work to detect errors with the initial driver setup? If the database is not up, it is not caught at this point, and the Python program fails and shows all the correct messages.

try:
 driver = GraphDatabase.driver("bolt://localhost:7687", auth=basic_auth( ...
except:
 exit( ...

Yet Python is able to catch errors if the next step fails for some reason, and I can get control:

try:
 session = driver.session()
except:
 exit( ...
1 ACCEPTED SOLUTION

Depending on the driver version you are using, this will not work. Try using driver.verify_connectivity(). There is also no need to wrap that in a try just to call exit in the except block. Should the driver fail to establish a connection (during the verify_connectivity call), it will raise en exception and that will terminate the interpreter if not caught. Additionally, you get the benefit of not masking the actual cause of the failure by just silently exiting the program.

View solution in original post

7 REPLIES 7

I am using the Java driver. I am able to create the driver and a session without the database being available. I get the exception below after a timeout period when trying to access an unavailable database through a transaction from the session.

org.neo4j.driver.exceptions.ServiceUnavailableException: Unable to connect to localhost:7687, ensure the database is running and that there is a working network connection to it.

Depending on the driver version you are using, this will not work. Try using driver.verify_connectivity(). There is also no need to wrap that in a try just to call exit in the except block. Should the driver fail to establish a connection (during the verify_connectivity call), it will raise en exception and that will terminate the interpreter if not caught. Additionally, you get the benefit of not masking the actual cause of the failure by just silently exiting the program.

That worked, except it displayed

ExperimentalWarning: The configuration may change in the future.
  driver.verify_connectivity()

In the API documentation I found this method of suppressing it:

import warnings
from neo4j import ExperimentalWarning
warnings.filterwarnings("ignore", category=ExperimentalWarning)

I changed my code to this:

driver = GraphDatabase.driver("bolt://localhost:7687", auth=basic_auth(...

try:
 driver.verify_connectivity()
except:
 exit( f"{logtime()} ... Failed Neo4j connectivity test.")

# Should be good. Cannot 'try' driver.session itself.
session = driver.session()

I thought it would be good to use an "except ExperimentalWarning:" block to suppress just that warning in just that one place in my code, but I could not get any variation of that to work. So the global suppression of experimental will do.

Thank you so much!

Glad I could help.

You can suppress warnings locally like so:

import warnings
from neo4j import ExperimentalWarning

driver = ...

with warnings.catch_warnings():
    warnings.filterwarnings("ignore", category=ExperimentalWarning)
    driver.verify_connectivity()

It's a good idea I suppose because that way you'll notice should you come across other experimental API parts.

steves
Node Clone

@rouven_bauer I am trying to get the exception using the try-except:

warnings.filterwarnings("ignore", category=ExperimentalWarning)
try:
driver.verify_connectivity()
doing a lot of interesting things here.....
except:
exit( f"Failed Neo4j connectivity test.")

If there is a connectivity, then do all the logic, if there is no connectivity, raise the driver.verify_connectivity() error:

---------------------------------------------------------------------------
ServiceUnavailable                        Traceback (most recent call last)
Input In [5], in <cell line: 1>()
      1 with warnings.catch_warnings():
      2     warnings.filterwarnings("ignore", category=ExperimentalWarning)
----> 3     driver.verify_connectivity()

File ~/Library/Python/3.8/lib/python/site-packages/neo4j/meta.py:85, in experimental.<locals>.f__.<locals>.f_(*args, **kwargs)
     83 from warnings import warn
     84 warn(message, category=ExperimentalWarning, stacklevel=2)
---> 85 return f(*args, **kwargs)

File ~/Library/Python/3.8/lib/python/site-packages/neo4j/__init__.py:445, in Neo4jDriver.verify_connectivity(self, **config)
    441 """
    442 :raise ServiceUnavailable: raised if the server does not support routing or if routing support is broken.
    443 """
    444 # TODO: Improve and update Stub Test Server to be able to test.
--> 445 return self._verify_routing_connectivity()

File ~/Library/Python/3.8/lib/python/site-packages/neo4j/__init__.py:471, in Neo4jDriver._verify_routing_connectivity(self)
    469     if val is not None:
    470         return routing_info
--> 471 raise ServiceUnavailable("Could not connect to any routing servers.")

ServiceUnavailable: Could not connect to any routing servers.

rouven_bauer
Neo4j
Neo4j

I'm not sure I fully understand what you're trying to achieve. But if I understand you right, you want the potential error of verify_connectivity to propagate and skip all your work.

If so, you could do it like that:

 

def interesting_things_with_the_driver(driver):
    with driver.session(...) as session:
        ...  # do the interesting stuff here


def main():
    # the with block (context manager) takes care of closing the driver.
    with neo4j.GraphDatabase.driver(...) as driver:
        driver.verify_connectivity()  # raises if there's no connectivity
        interesting_things_with_the_driver(driver)


def alternative_main():
    driver = neo4j.GraphDatabase.driver(...)
    try:
        driver.verify_connectivity()  # raises if there's no connectivity
        # only gets executes if verify_connectivity succeeded
        interesting_things_with_the_driver(driver)
    finally:
        # regardless if we fail or not, the driver needs to be closed to free
        # all resources
        driver.close()

 

steves
Node Clone

Thanks @rouven_bauer