Source code for weaver.exceptions
"""
Errors raised during the weaver flow.
"""
import logging
from functools import wraps
from typing import TYPE_CHECKING
from pyramid.httpexceptions import HTTPException, HTTPInternalServerError
from pyramid.request import Request as PyramidRequest
from pyramid.testing import DummyRequest
from requests import Request as RequestsRequest
[docs]LOGGER = logging.getLogger(__name__)
if TYPE_CHECKING:
from typing import Any, AnyStr, Callable, Type
[docs]class WeaverException(Exception):
"""Base class of exceptions defined by :mod:`weaver` package."""
[docs]class InvalidIdentifierValue(WeaverException, ValueError):
"""
Error indicating that an id to be employed for following operations
is not considered as valid to allow further processed or usage.
"""
[docs]class ServiceException(WeaverException):
"""Base exception related to a :class:`weaver.datatype.Service`."""
[docs]class ServiceNotAccessible(ServiceException):
"""
Error indicating that a WPS service exists but is not visible to retrieve
from the storage backend of an instance of :class:`weaver.store.ServiceStore`.
"""
[docs]class ServiceNotFound(ServiceException):
"""
Error indicating that an OWS service could not be read from the
storage backend by an instance of :class:`weaver.store.ServiceStore`.
"""
[docs]class ServiceRegistrationError(ServiceException):
"""
Error indicating that an OWS service could not be registered in the
storage backend by an instance of :class:`weaver.store.ServiceStore`.
"""
[docs]class ProcessException(WeaverException):
"""Base exception related to a :class:`weaver.datatype.Process`."""
[docs]class ProcessNotAccessible(ProcessException):
"""
Error indicating that a local WPS process exists but is not visible to retrieve
from the storage backend of an instance of :class:`weaver.store.ProcessStore`.
"""
[docs]class ProcessNotFound(ProcessException):
"""
Error indicating that a local WPS process could not be read from the
storage backend by an instance of :class:`weaver.store.ProcessStore`.
"""
[docs]class ProcessRegistrationError(ProcessException):
"""
Error indicating that a WPS process could not be registered in the
storage backend by an instance of :class:`weaver.store.ProcessStore`.
"""
[docs]class ProcessInstanceError(ProcessException):
"""
Error indicating that the process instance passed is not supported with
storage backend by an instance of :class:`weaver.store.ProcessStore`.
"""
[docs]class JobException(WeaverException):
"""Base exception related to a :class:`weaver.datatype.Job`."""
[docs]class JobNotFound(JobException):
"""
Error indicating that a job could not be read from the
storage backend by an instance of :class:`weaver.store.JobStore`.
"""
[docs]class JobRegistrationError(JobException):
"""
Error indicating that a job could not be registered in the
storage backend by an instance of :class:`weaver.store.JobStore`.
"""
[docs]class JobUpdateError(JobException):
"""
Error indicating that a job could not be updated in the
storage backend by an instance of :class:`weaver.store.JobStore`.
"""
[docs]class PackageException(WeaverException):
"""Base exception related to a :class:`weaver.processes.wps_package.Package`."""
[docs]class PackageTypeError(PackageException):
"""
Error indicating that an instance of :class:`weaver.processes.wps_package.Package`
could not properly parse input/output type(s) for package deployment or execution.
"""
[docs]class PackageRegistrationError(PackageException):
"""
Error indicating that an instance of :class:`weaver.processes.wps_package.Package`
could not properly be registered for package deployment because of invalid prerequisite.
"""
[docs]class PackageExecutionError(PackageException):
"""
Error indicating that an instance of :class:`weaver.processes.wps_package.Package`
could not properly execute the package using provided inputs and package definition.
"""
[docs]class PackageNotFound(PackageException):
"""
Error indicating that an instance of :class:`weaver.processes.wps_package.Package`
could not properly retrieve the package definition using provided references.
"""
[docs]class PayloadNotFound(PackageException):
"""
Error indicating that an instance of :class:`weaver.processes.wps_package.Package`
could not properly retrieve the package deploy payload using provided references.
"""
[docs]class QuoteException(WeaverException):
"""Base exception related to a :class:`weaver.datatype.Quote`."""
[docs]class QuoteNotFound(QuoteException):
"""
Error indicating that a quote could not be read from the
storage backend by an instance of :class:`weaver.store.QuoteStore`.
"""
[docs]class QuoteRegistrationError(QuoteException):
"""
Error indicating that a quote could not be registered in the
storage backend by an instance of :class:`weaver.store.QuoteStore`.
"""
[docs]class QuoteInstanceError(QuoteException):
"""
Error indicating that a given object doesn't correspond to an expected
instance of :class:`weaver.datatype.Quote`.
"""
[docs]class BillException(WeaverException):
"""Base exception related to a :class:`weaver.datatype.Bill`."""
[docs]class BillNotFound(BillException):
"""
Error indicating that a bill could not be read from the
storage backend by an instance of :class:`weaver.store.BillStore`.
"""
[docs]class BillRegistrationError(BillException):
"""
Error indicating that a bill could not be registered in the
storage backend by an instance of :class:`weaver.store.BillStore`.
"""
[docs]class BillInstanceError(BillException):
"""
Error indicating that a given object doesn't correspond to an expected
instance of :class:`weaver.datatype.Bill`.
"""
[docs]def log_unhandled_exceptions(logger=LOGGER, message="Unhandled exception occurred.", exception=Exception,
force=False, require_http=True, is_request=True):
# type: (logging.Logger, AnyStr, Type[Exception], bool, bool, bool) -> Callable
"""
Decorator that will raise ``exception`` with specified ``message`` if an exception is caught while execution the
wrapped function, after logging relevant details about the caught exception with ``logger``.
:param logger: logger to use for logging (default: use :data:`weaver.exception.LOGGER`).
:param message: message that will be logged with details and then raised with ``exception``.
:param exception: exception type to be raised instead of the caught exception.
:param force: force handling of any raised exception (default: only *known* unhandled exceptions are logged).
:param require_http:
consider non HTTP-like exceptions as *unknown* and raise one instead
(default: ``True`` and raises :class:`HTTPInternalServerError`, unless ``exception`` is HTTP-like).
:param is_request: specifies if the decorator is applied onto a registered request function to handle its inputs.
:raises exception: if an *unknown* exception was caught (or forced) during the decorated function's execution.
:raises Exception: original exception if it is *known*.
"""
from weaver.owsexceptions import OWSException # avoid circular import error
known_exceptions = [WeaverException]
known_http_exceptions = [HTTPException, OWSException]
if require_http:
if not issubclass(exception, tuple(known_http_exceptions)):
exception = HTTPInternalServerError
known_exceptions.extend(known_http_exceptions)
known_exceptions = tuple(known_exceptions)
def wrap(function):
# type: (Callable[[Any, Any], Any]) -> Callable
@wraps(function)
def call(*args, **kwargs):
try:
# handle input arguments that are extended by various pyramid operations
if is_request:
while len(args) and not isinstance(args[0], (RequestsRequest, PyramidRequest, DummyRequest)):
args = args[1:]
return function(*args, **kwargs)
except Exception as exc:
# if exception was already handled by this wrapper from a previously wrapped function,
# just re-raise the exception without over-logging it recursively
handle = "__LOG_UNHANDLED_EXCEPTION__"
if not hasattr(exc, handle):
setattr(exc, handle, True) # mark as handled
# unless specified to log any type, raise only known exceptions
if force or not isinstance(exc, known_exceptions):
setattr(exception, handle, True) # mark as handled
setattr(exception, "error", exc) # make original exception available through new one raised
logger.exception("%s%s[%r]", message, (" " if message else "") + "Exception: ", exc)
raise exception(message)
raise exc
return call
return wrap