omrakhur
omrakhur

Reputation: 1402

Pymongo Exception handling not working right in python 3

I'm running a script to check if pymongo exceptions are successfully caught, but so far the only errors I get are Pycharm IDE errors. I turned the mongo daemon off to test this out. The relevant portion of the script is as follows, with IDE errors following after it:

import pymongo
from pymongo import MongoClient
from pymongo import errors
import os
from os.path import basename

def make_collection_name(path):
    filename = os.path.splitext(basename(path))[0]
    collection_name = filename
    if collection_name in db.collection_names():
        db[collection_name].drop()
    return collection_name

if __name__ == '__main__':

    try:
        client = MongoClient()
    except pymongo.errors.ConnectionFailure as e:
        print("Could not connect to MongoDB: %s") % e
    except pymongo.errors.ServerSelectionTimeoutError as e:
        print("Could not connect to MongoDB: %s") % e
    filepath = **hidden filepath**
    db = client.TESTDB

    collection_name = make_collection_name(filepath)

Instead of having the exceptions handled, I rather get the following errors from the IDE:

Traceback (most recent call last):
  File "**hidden path**", line 278, in <module>
    collection_name = make_collection_name(filepath)
  File "**hidden path**", line 192, in make_collection_name
    if collection_name in db.collection_names():
  File "C:\Python34\lib\site-packages\pymongo\database.py", line 530, in collection_names
    ReadPreference.PRIMARY) as (sock_info, slave_okay):
  File "C:\Python34\lib\contextlib.py", line 59, in __enter__
    return next(self.gen)
  File "C:\Python34\lib\site-packages\pymongo\mongo_client.py", line 859, in _socket_for_reads
    with self._get_socket(read_preference) as sock_info:
  File "C:\Python34\lib\contextlib.py", line 59, in __enter__
    return next(self.gen)
  File "C:\Python34\lib\site-packages\pymongo\mongo_client.py", line 823, in _get_socket
    server = self._get_topology().select_server(selector)
  File "C:\Python34\lib\site-packages\pymongo\topology.py", line 214, in select_server
    address))
  File "C:\Python34\lib\site-packages\pymongo\topology.py", line 189, in select_servers
    self._error_message(selector))
pymongo.errors.ServerSelectionTimeoutError: localhost:27017: [WinError 10061] No connection could be made because the target machine actively refused it

Process finished with exit code 1

Upvotes: 2

Views: 5578

Answers (1)

A. Jesse Jiryu Davis
A. Jesse Jiryu Davis

Reputation: 24007

Beginning in PyMongo 3 (not Python 3, PyMongo 3!), the MongoClient constructor no longer blocks trying to connect to the MongoDB server. Instead, the first actual operation you do will wait until the connection completes, and then throw an exception if connection fails.

http://api.mongodb.com/python/current/migrate-to-pymongo3.html#mongoclient-connects-asynchronously

As you can see from your stack trace, the exception is thrown from db.collection_names(), not from MongoClient(). So, wrap your call to make_collection_name in try / except, not the MongoClient call.

Upvotes: 4

Related Questions