Source code for VestaRestPackage.vesta_exceptions

import future

# -- Standard lib ------------------------------------------------------------
import http.client as httplib

# -- Project specific --------------------------------------------------------
from . import singleton


[docs]class ExceptionInfo: """ Exception information to show useful responses to user when they happen. """ def __init__(self, code, exc_type, status=httplib.INTERNAL_SERVER_ERROR, msg=None): """ Constructor. :param code: Vesta exception code :param exc_type: Exception type :param status: HTTP status code to send with the request response :param msg: Generic message to show for a particular exception If None, the specific message contains in the exception will be used. So if a generic one is provided the specific message will be overridden with it. """ self.code = code self.exc_type = exc_type self.status = status self.msg = msg
@singleton.Singleton class VestaExceptions(object): """ Exceptions register class. """ def __init__(self): """ Populate the known exceptions list. """ self._known_exceptions = [ # ----------------------------------------------------------------- # 1xx exception codes are reserved for built-in exceptions # ----------------------------------------------------------------- ExceptionInfo(code=100, exc_type='NoneType'), ExceptionInfo(code=101, exc_type='Exception'), ExceptionInfo(code=102, exc_type='sqlite3.Error'), ExceptionInfo(code=103, exc_type='ConfigParser.Error'), ExceptionInfo(code=104, exc_type='TypeError'), ExceptionInfo(code=105, exc_type='ValueError'), ExceptionInfo(code=106, exc_type='socket.gaierror'), ExceptionInfo(code=107, exc_type='IOError'), ExceptionInfo(code=108, exc_type='KeyError'), ExceptionInfo(code=109, exc_type='TaskRevokedError'), # ----------------------------------------------------------------- # 2xx exception codes are reserved for VRP package # ----------------------------------------------------------------- ExceptionInfo(code=200, exc_type='SettingsException'), ExceptionInfo(code=201, exc_type='VersionException'), ExceptionInfo(code=202, exc_type='UnknownServiceError', status=httplib.BAD_REQUEST), ExceptionInfo(code=203, exc_type='UnknownUUIDError', status=httplib.BAD_REQUEST), ExceptionInfo(code=204, exc_type='VersionMismatchError'), ExceptionInfo(code=205, exc_type='AMQPError', status=httplib.REQUEST_TIMEOUT), ExceptionInfo(code=206, exc_type='MissingParameterError', status=httplib.BAD_REQUEST), ExceptionInfo(code=207, exc_type='DocumentUrlNotValidException', status=httplib.BAD_REQUEST), # ----------------------------------------------------------------- # 3xx exception codes are reserved for Service package # ----------------------------------------------------------------- ExceptionInfo(code=300, exc_type='InvalidAnnotationFormat'), ExceptionInfo(code=301, exc_type='DownloadError'), ExceptionInfo(code=302, exc_type='UploadError'), ExceptionInfo(code=303, exc_type='ConfigFileNotFound'), ExceptionInfo(code=304, exc_type='InvalidDocumentPath'), ExceptionInfo(code=305, exc_type='InvalidDocumentType'), ExceptionInfo(code=306, exc_type='RuntimeError'), # ----------------------------------------------------------------- # 4xx exception codes are reserved for VLB package # ----------------------------------------------------------------- ExceptionInfo(code=400, exc_type='InsufficientResources'), ExceptionInfo(code=401, exc_type='MinimumWorkersReached'), # ----------------------------------------------------------------- # 5xx exception codes are reserved for MSS package # ----------------------------------------------------------------- ExceptionInfo(code=500, exc_type='OverflowError'), ExceptionInfo(code=501, exc_type='NotImplementedError'), ExceptionInfo(code=502, exc_type='FFMpegError'), ExceptionInfo(code=503, exc_type='FFMpegConvertError'), ExceptionInfo(code=504, exc_type='ConverterError'), ExceptionInfo(code=505, exc_type='TranscoderError'), # A message must absolutely be set here because specific message # contains sensible data ExceptionInfo(code=506, exc_type='SwiftException', msg='Cannot renew the swift token'), # ----------------------------------------------------------------- # 600 and above exceptions codes are free to be used by workers # ----------------------------------------------------------------- # 600-620 exceptions codes are taken by transition/face worker ExceptionInfo(code=600, exc_type='CInternalError'), # 630-639 onwards shared by diarization, STT, TextMatching. ExceptionInfo(code=630, exc_type="WavPathInvalid"), ExceptionInfo(code=631, exc_type="WavFormatInvalid"), ExceptionInfo(code=632, exc_type="WavHeaderInvalid"), ExceptionInfo(code=633, exc_type="SubprocessProblem", msg="Diarisation worker internal problem"), # 640 onwards taken by STT. ExceptionInfo(code=640, exc_type="PathInvalidError"), ExceptionInfo(code=641, exc_type="SegmentsTooLongException"), ExceptionInfo(code=642, exc_type="SubprocessError"), ExceptionInfo(code=643, exc_type="TranscriptionEmptyError"), ] # Make an exception dict based on exception type from the list above self._known_exceptions_dict = dict((exc.exc_type, exc) for exc in self._known_exceptions) def __find_matching_exception(self, exception): """ Try to find a matching exception class in the known exception dictionary. :param exception: The exception class :returns: An exception object (A generic one is returned if not found) """ exception_type_name = type(exception).__name__ # First, try a direct match if exception_type_name in self._known_exceptions_dict: return self._known_exceptions_dict[exception_type_name] # Then make a search including some or all of the module directories try: module_dirs = exception.__module__.split('.') for mod_dir in reversed(module_dirs): exception_type_name = ''.join([mod_dir, '.', exception_type_name]) if exception_type_name in self._known_exceptions_dict: return self._known_exceptions_dict[exception_type_name] except AttributeError: # Not all exceptions have a __module__ attribute pass # Return a generic exception to handle this unknown exception return self._known_exceptions_dict['Exception'] def get_exception_code(self, exception): """ Returns the Vesta exception code associated to this exception. :param exception: Exception instance :returns: Exception code """ return self.__find_matching_exception(exception).code def get_html_status(self, exception): """ Returns the html status code associated to this exception. :param exception: Exception instance :returns: HTML status code """ return self.__find_matching_exception(exception).status def get_generic_message(self, exception): """ Returns the generic message associated to this exception. :param exception: Exception instance :returns: Exception message """ return self.__find_matching_exception(exception).msg
[docs]class VRPException(Exception): """ Base exception type for current package. """ status_code = 400 def __init__(self, message, status_code=None, payload=None): Exception.__init__(self) self.message = message if status_code is not None: self.status_code = status_code self.payload = payload def to_dict(self): rv = dict(self.payload or ()) rv['message'] = self.message return rv
[docs]class UnknownServiceError(VRPException): """ Indicates that a Service name is of unknown type. """ def __init__(self, service): msg = ('The request has been made for a service that is not supported' ' : {service}'.format(service=service)) super(UnknownServiceError, self).__init__(msg)
[docs]class UnknownUUIDError(VRPException): """ Indicates that the requested UUID is not yet registered. """ def __init__(self, uuid): msg = ('User requested a UUID which did not exist : {uuid}' .format(uuid=uuid)) super(UnknownUUIDError, self).__init__(msg)
[docs]class MissingParameterError(VRPException): """ Indicates that a required parameter is missing. """ def __init__(self, method, uri, missing_param): msg = ('A {method} on the URI "{uri}" requires the following ' 'parameter : {param}'.format(method=method, uri=uri, param=missing_param)) super(MissingParameterError, self).__init__(msg)
[docs]class VersionMismatchError(VRPException): """ Indicates that a service version declared in the REST configuration mismatches the version obtained from worker message payload. """ pass
[docs]class AMQPError(VRPException): """ Indicates that communications with AMQP failed. """ def __init__(self): msg = "AMQP backend didn't response quickly enough." super(AMQPError, self).__init__(msg)
[docs]class DocumentUrlNotValidException(VRPException): """ Indicates that given URL for a document is invalid. """ def __init__(self, invalid_url): msg = ('User provided an invalid source URL : {url}' .format(url=invalid_url)) super(DocumentUrlNotValidException, self).__init__(msg)
[docs]class SettingsException(VRPException): """ Indicates that an error occurred during settings parsing. """ pass
[docs]class VersionException(VRPException): """ Indicates that a version mismatch was found. """ pass