Better exception handling

This commit is contained in:
vrde 2017-01-31 02:07:36 +01:00
parent a8bbc87c1c
commit 1557645e94
No known key found for this signature in database
GPG Key ID: 6581C7C39B3D397D
4 changed files with 23 additions and 11 deletions

View File

@ -1,5 +1,8 @@
from bigchaindb.exceptions import BigchainDBError
class ConnectionError(BigchainDBError):
"""Exception raised when the connection to the DataBase fails."""
class DatabaseOpFailedError(BigchainDBError):
"""Exception for database operation errors."""

View File

@ -8,7 +8,8 @@ from bigchaindb import backend
from bigchaindb.backend.changefeed import ChangeFeed
from bigchaindb.backend.utils import module_dispatch_registrar
from bigchaindb.backend.mongodb.connection import MongoDBConnection
from bigchaindb.backend.exceptions import (DatabaseOpFailedError,
ConnectionError)
logger = logging.getLogger(__name__)
register_changefeed = module_dispatch_registrar(backend.changefeed)
@ -31,7 +32,8 @@ class MongoDBChangeFeed(ChangeFeed):
break
except (errors.ConnectionFailure, errors.OperationFailure,
errors.AutoReconnect,
errors.ServerSelectionTimeoutError) as exc:
errors.ServerSelectionTimeoutError,
DatabaseOpFailedError, ConnectionError) as exc:
logger.exception(exc)
time.sleep(1)

View File

@ -8,6 +8,7 @@ from pymongo import errors
import bigchaindb
from bigchaindb.utils import Lazy
from bigchaindb.common import exceptions
from bigchaindb.backend import exceptions as backend_exceptions
from bigchaindb.backend.connection import Connection
logger = logging.getLogger(__name__)
@ -51,7 +52,7 @@ class MongoDBConnection(Connection):
@property
def conn(self):
if self.connection is None:
self.connection = self._connect()
self._connect()
return self.connection
@property
@ -77,23 +78,24 @@ class MongoDBConnection(Connection):
try:
# FYI: this might raise a `ServerSelectionTimeoutError`,
# that is a subclass of `ConnectionFailure`.
connection = MongoClient(self.host,
self.port,
replicaset=self.replicaset,
serverselectiontimeoutms=self.connection_timeout)
self.connection = MongoClient(self.host,
self.port,
replicaset=self.replicaset,
serverselectiontimeoutms=self.connection_timeout)
# we should only return a connection if the replica set is
# initialized. initialize_replica_set will check if the
# replica set is initialized else it will initialize it.
initialize_replica_set(self.host, self.port, self.connection_timeout)
return connection
except (errors.ConnectionFailure, errors.AutoReconnect) as exc:
logger.warning('Attempt %s/%s. Connection to %s:%s failed after %sms.',
attempt, self.max_tries if self.max_tries != 0 else '',
self.host, self.port, self.connection_timeout)
if attempt == self.max_tries:
logger.exception('Cannot connect to the Database. Giving up.')
raise errors.ConnectionFailure() from exc
logger.critical('Cannot connect to the Database. Giving up.')
raise backend_exceptions.ConnectionError() from exc
else:
break
def collection(name):

View File

@ -23,7 +23,8 @@ from bigchaindb.utils import ProcessGroup
from bigchaindb import backend
from bigchaindb.backend import schema
from bigchaindb.backend.admin import set_replicas, set_shards
from bigchaindb.backend.exceptions import DatabaseOpFailedError
from bigchaindb.backend.exceptions import (DatabaseOpFailedError,
ConnectionError)
from bigchaindb.commands import utils
from bigchaindb import processes
@ -157,6 +158,8 @@ def run_init(args):
except DatabaseAlreadyExists:
print('The database already exists.', file=sys.stderr)
print('If you wish to re-initialize it, first drop it.', file=sys.stderr)
except ConnectionError:
print('Cannot connect to the database.', file=sys.stderr)
def run_drop(args):
@ -201,6 +204,8 @@ def run_start(args):
_run_init()
except DatabaseAlreadyExists:
pass
except ConnectionError:
print('Cannot connect to the database.', file=sys.stderr)
except KeypairNotFoundException:
sys.exit("Can't start BigchainDB, no keypair found. "
'Did you run `bigchaindb configure`?')