def convert_exception(exc, *args): new_args = exc.args + args if isinstance(exc, gorpc.TimeoutError): return dbexceptions.TimeoutError(new_args) elif isinstance(exc, gorpc.AppError): msg = str(exc[0]).lower() if msg.startswith('retry'): return dbexceptions.RetryError(new_args) if msg.startswith('fatal'): return dbexceptions.FatalError(new_args) if msg.startswith('tx_pool_full'): return dbexceptions.TxPoolFull(new_args) match = _errno_pattern.search(msg) if match: mysql_errno = int(match.group(1)) if mysql_errno == 1062: return dbexceptions.IntegrityError(new_args) # TODO(sougou/liguo): remove this case once servers are deployed elif mysql_errno == 1290 and 'read-only' in msg: return dbexceptions.RetryError(new_args) return dbexceptions.DatabaseError(new_args) elif isinstance(exc, gorpc.ProgrammingError): return dbexceptions.ProgrammingError(new_args) elif isinstance(exc, gorpc.GoRpcError): return dbexceptions.FatalError(new_args) return exc
def _run_with_reconnect(self, *args, **kargs): attempt = 0 while True: try: return method(self, *args, **kargs) except (dbexceptions.RetryError, dbexceptions.FatalError, dbexceptions.TxPoolFull) as e: attempt += 1 # Execution attempt failed with OperationalError, re-read the keyspace. if not isinstance(e, dbexceptions.TxPoolFull): self.resolve_topology() if attempt >= self.max_attempts or self.in_txn: self.close() vtdb_logger.get_logger().vtclient_exception( self.keyspace, self.shard, self.db_type, e) raise dbexceptions.FatalError(*e.args) if method.__name__ == 'begin': time.sleep(BEGIN_RECONNECT_DELAY) else: time.sleep(RECONNECT_DELAY) if not isinstance(e, dbexceptions.TxPoolFull): logging.info("Attempting to reconnect, %d", attempt) self.close() self.connect() logging.info("Successfully reconnected to %s", str(self.conn)) else: logging.info( "Waiting to retry for dbexceptions.TxPoolFull to %s, attempt %d", str(self.conn), attempt)
def _convert_exception(self, exc, *args, **kwargs): """This parses the protocol exceptions to the api interface exceptions. This also logs the exception and increments the appropriate error counters. Args: exc: raw protocol exception. *args: additional args from the raising site. **kwargs: additional keyword args from the raising site. Returns: Api interface exceptions - dbexceptions with new args. """ new_args = exc.args + (str(self), ) + args if kwargs: new_args += tuple(sorted(kwargs.itervalues())) new_exc = exc if isinstance(exc, gorpc.TimeoutError): new_exc = dbexceptions.TimeoutError(new_args) elif isinstance(exc, vtgate_utils.VitessError): new_exc = exc.convert_to_dbexception(new_args) elif isinstance(exc, gorpc.ProgrammingError): new_exc = dbexceptions.ProgrammingError(new_args) elif isinstance(exc, gorpc.GoRpcError): new_exc = dbexceptions.FatalError(new_args) keyspace_name = kwargs.get('keyspace', None) tablet_type = kwargs.get('tablet_type', None) vtgate_utils.log_exception(new_exc, keyspace=keyspace_name, tablet_type=tablet_type) return new_exc
def _convert_exception(self, exc, *args, **kwargs): """This parses the protocol exceptions to the api interface exceptions. This also logs the exception and increments the appropriate error counters. Args: exc: raw protocol exception. *args: additional args from the raising site. **kwargs: additional keyword args from the raising site. Returns: Api interface exceptions - dbexceptions with new args. """ kwargs_as_str = vtgate_utils.convert_exception_kwargs(kwargs) exc.args += args if kwargs_as_str: exc.args += kwargs_as_str, new_args = (type(exc).__name__,) + exc.args if isinstance(exc, gorpc.TimeoutError): new_exc = dbexceptions.TimeoutError(new_args) elif isinstance(exc, vtgate_utils.VitessError): new_exc = exc.convert_to_dbexception(new_args) elif isinstance(exc, gorpc.ProgrammingError): new_exc = dbexceptions.ProgrammingError(new_args) elif isinstance(exc, gorpc.GoRpcError): new_exc = dbexceptions.FatalError(new_args) else: new_exc = exc vtgate_utils.log_exception( new_exc, keyspace=kwargs.get('keyspace'), tablet_type=kwargs.get('tablet_type')) return new_exc
def handle_app_error(exc_args): msg = str(exc_args[0]).lower() # Operational Error if msg.startswith('retry'): return dbexceptions.RetryError(exc_args) if msg.startswith('fatal'): return dbexceptions.FatalError(exc_args) if msg.startswith('tx_pool_full'): return dbexceptions.TxPoolFull(exc_args) # Integrity and Database Error match = _errno_pattern.search(msg) if match: # Prune the error message to truncate after the mysql errno, since # the error message may contain the query string with bind variables. mysql_errno = int(match.group(1)) if mysql_errno == 1062: parts = _errno_pattern.split(msg) pruned_msg = msg[:msg.find(parts[2])] new_args = (pruned_msg, ) + tuple(exc_args[1:]) return dbexceptions.IntegrityError(new_args) # TODO(sougou/liguo): remove this case once servers are deployed elif mysql_errno == 1290 and 'read-only' in msg: return dbexceptions.RetryError(exc_args) return dbexceptions.DatabaseError(exc_args)
def _run_with_reconnect(self, *args, **kargs): attempt = 0 while True: try: return method(self, *args, **kargs) except (dbexceptions.RetryError, dbexceptions.FatalError, dbexceptions.TxPoolFull) as e: attempt += 1 if attempt >= self.max_attempts or self.in_txn: self.close() raise dbexceptions.FatalError(*e.args) if method.__name__ == 'begin': time.sleep(BEGIN_RECONNECT_DELAY) else: time.sleep(RECONNECT_DELAY) if not isinstance(e, dbexceptions.TxPoolFull): logging.info("Attempting to reconnect, %d", attempt) self.close() self.connect() logging.info("Successfully reconnected to %s", str(self.conn)) else: logging.info( "Waiting to retry for dbexceptions.TxPoolFull to %s, attempt %d", str(self.conn), attempt)
def convert_to_dbexception(self, args): """Converts from a TabletError to the appropriate dbexceptions class. Args: args: argument tuple to use to create the new exception. Returns: An exception from dbexceptions. """ if self.code == vtrpc_pb2.QUERY_NOT_SERVED: return dbexceptions.RetryError(args) if self.code == vtrpc_pb2.INTERNAL_ERROR: return dbexceptions.FatalError(args) if self.code == vtrpc_pb2.RESOURCE_EXHAUSTED: return dbexceptions.TxPoolFull(args) if self.code == vtrpc_pb2.INTEGRITY_ERROR: # Prune the error message to truncate after the mysql errno, since # the error message may contain the query string with bind variables. msg = self.message.lower() parts = self._errno_pattern.split(msg) pruned_msg = msg[:msg.find(parts[2])] new_args = (pruned_msg,) + tuple(args[1:]) return dbexceptions.IntegrityError(new_args) return dbexceptions.DatabaseError(args)
def convert_exception(exc, *args, **kwargs): """This parses the protocol exceptions to the api interface exceptions. This also logs the exception and increments the appropriate error counters. Args: exc: raw protocol exception. args: additional args from the raising site. kwargs: additional keyword args from the raising site. Returns: Api interface exceptions - dbexceptions with new args. """ new_args = exc.args + args if kwargs: new_args += tuple(kwargs.itervalues()) new_exc = exc if isinstance(exc, gorpc.TimeoutError): new_exc = dbexceptions.TimeoutError(new_args) elif isinstance(exc, gorpc.AppError): new_exc = handle_app_error(new_args) elif isinstance(exc, gorpc.ProgrammingError): new_exc = dbexceptions.ProgrammingError(new_args) elif isinstance(exc, gorpc.GoRpcError): new_exc = dbexceptions.FatalError(new_args) keyspace = kwargs.get("keyspace", None) tablet_type = kwargs.get("tablet_type", None) vtgate_utils.log_exception(new_exc, keyspace=keyspace, tablet_type=tablet_type) return new_exc
def convert_exception(exc, *args): new_args = exc.args + args if isinstance(exc, gorpc.TimeoutError): return dbexceptions.TimeoutError(new_args) elif isinstance(exc, gorpc.AppError): return handle_app_error(new_args) elif isinstance(exc, gorpc.ProgrammingError): return dbexceptions.ProgrammingError(new_args) elif isinstance(exc, gorpc.GoRpcError): return dbexceptions.FatalError(new_args) return exc
def convert_exception(exc, *args): new_args = exc.args + args if isinstance(exc, gorpc.TimeoutError): return dbexceptions.TimeoutError(new_args) elif isinstance(exc, TabletError): return exc.convert_to_dbexception(new_args) elif isinstance(exc, gorpc.ProgrammingError): return dbexceptions.ProgrammingError(new_args) elif isinstance(exc, gorpc.GoRpcError): return dbexceptions.FatalError(new_args) return exc
def convert_exception(exc, *args): """Return an exception object expected by callers.""" new_args = exc.args + args if isinstance(exc, gorpc.TimeoutError): return dbexceptions.TimeoutError(new_args) elif isinstance(exc, vtgate_utils.VitessError): return exc.convert_to_dbexception(new_args) elif isinstance(exc, gorpc.ProgrammingError): return dbexceptions.ProgrammingError(new_args) elif isinstance(exc, gorpc.GoRpcError): return dbexceptions.FatalError(new_args) return exc
def convert_exception(exc, *args): new_args = exc.args + args if isinstance(exc, gorpc.TimeoutError): return dbexceptions.TimeoutError(new_args) elif isinstance(exc, gorpc.AppError): msg = str(exc[0]).lower() if msg.startswith('retry'): return dbexceptions.RetryError(new_args) if msg.startswith('fatal'): return dbexceptions.FatalError(new_args) if msg.startswith('tx_pool_full'): return dbexceptions.TxPoolFull(new_args) match = _errno_pattern.search(msg) if match: mysql_errno = int(match.group(1)) return _errno_map.get(mysql_errno, dbexceptions.DatabaseError)(new_args) return dbexceptions.DatabaseError(new_args) elif isinstance(exc, gorpc.ProgrammingError): return dbexceptions.ProgrammingError(new_args) elif isinstance(exc, gorpc.GoRpcError): return dbexceptions.FatalError(new_args) return exc
def convert_exception(exc, *args): new_args = exc.args + args vtdb_logger.get_logger().vtgatev2_exception(exc) if isinstance(exc, gorpc.TimeoutError): return dbexceptions.TimeoutError(new_args) elif isinstance(exc, gorpc.AppError): msg = str(exc[0]).lower() match = _errno_pattern.search(msg) if match: mysql_errno = int(match.group(1)) if mysql_errno == 1062: return dbexceptions.IntegrityError(new_args) return dbexceptions.DatabaseError(new_args) elif isinstance(exc, gorpc.ProgrammingError): return dbexceptions.ProgrammingError(new_args) elif isinstance(exc, gorpc.GoRpcError): return dbexceptions.FatalError(new_args) return exc
def convert_exception(exc, *args): new_args = exc.args + args if isinstance(exc, gorpc.TimeoutError): return dbexceptions.TimeoutError(new_args) elif isinstance(exc, gorpc.AppError): msg = str(exc[0]).lower() if msg.startswith('request_backlog'): return dbexceptions.RequestBacklog(new_args) match = _errno_pattern.search(msg) if match: mysql_errno = int(match.group(1)) if mysql_errno == 1062: return dbexceptions.IntegrityError(new_args) return dbexceptions.DatabaseError(new_args) elif isinstance(exc, gorpc.ProgrammingError): return dbexceptions.ProgrammingError(new_args) elif isinstance(exc, gorpc.GoRpcError): return dbexceptions.FatalError(new_args) return exc