<commit_before>"""Exception handling.
"""

import sys
from collections import Mapping
import suds

__all__ = [
    # helper
    'stripCause', 
    # Exceptions thrown by the ICAT or IDS server
    'ICATError', 'ICATParameterError', 'ICATInternalError', 
    'ICATPrivilegesError', 'ICATNoObjectError', 'ICATObjectExistsError', 
    'ICATSessionError', 'ICATValidationError', 
    'IDSError', 'IDSBadRequestError', 'IDSDataNotOnlineError', 
    'IDSInsufficientPrivilegesError', 'IDSInsufficientStorageError', 
    'IDSInternalError', 'IDSNotFoundError', 'IDSNotImplementedError', 
    'translateError', 
    # Internal error
    'InternalError', 
    # icat.config
    'ConfigError', 
    # icat.query
    'QueryNullableOrderWarning', 
    # icat.client, icat.entity
    'ClientVersionWarning', 'ICATDeprecationWarning', 'VersionMethodError', 
    'SearchResultError', 'SearchAssertionError', 'DataConsistencyError', 
    # icat.ids
    'IDSResponseError', 
    # icat.icatcheck
    'GenealogyError',
    ]


# ======================== helper function =========================

def stripCause(e):
    """Try to suppress misleading context from an exception.

    `Exception Chaining and Embedded Tracebacks`_ has been introduced
    with Python 3.  Unfortunately the result is completely misleading
    most of the times.  Try to suppress the context from the exception
    traceback.  This works with Python 3.3 and newer, but has no
    effect with Python 3.1 and 3.2.

    .. _Exception Chaining and Embedded Tracebacks: http://legacy.python.org/dev/peps/pep-3134/
    """
    if hasattr(e, '__cause__'):
        e.__cause__ = None
    return e


# ========== Exceptions thrown by the ICAT or IDS server ===========

class ServerError(Exception):
    """Errors raised by either the ICAT or the IDS server.

    This is the common base class for ICATError and IDSError, it is
    not intented to be raised directly.
    """
    def __init__(self, error, status):
        """Expecept either a suds.WebFault or a Mapping with the keys 'code',
        'message', and 'offset'.
        """
        if isinstance(error, suds.WebFault):
            try:
                message = self._convertmsg(error.fault.faultstring)
            except AttributeError:
                message = self._convertmsg(str(error))
            super(ServerError, self).__init__(message)
            self.status = status
            self.message = message
            self.fault = error.fault
            self.document = error.document
            try:
                icatexception = error.fault.detail.IcatException
            except AttributeError:
                pass
            else:
                self.type = getattr(icatexception, 'type', None)
                self.offset = getattr(icatexception, 'offset', None)
                if self.offset is not None and self.offset < 0:
                    self.offset = None
        elif isinstance(error, Mapping):
            # Deliberately not fetching KeyError here.  Require the
            # field to be present.  Only 'offset' is optional.
            message = self._convertmsg(error['message'])
            super(ServerError, self).__init__(message)
            self.status = status
            self.message = message
            self.type = str(error['code'])
            self.offset = error.get('offset', None)
        else:
            raise TypeError("Invalid argument type '%s'." % type(error))

    def _convertmsg(self, msg):
        # msg may be a str, a suds.sax.text.Text instance, or (only
        # for Python 2) an unicode instance.  In Python 2, we must
        # convert it to a pure ascii string for Exception.  In Python
        # 3, we convert it to a str.  It may still contain non-ascii
        # chars, but this is ok for Exception in Python 3.
        if sys.version_info < (3, 0):
            return msg.encode('ascii', errors='replace')
        else:
            return str(msg)


class ICATError(ServerError):
    """Base class for the errors raised by the ICAT server.
    """
    pass

class ICATParameterError(ICATError):
    """Generally indicates a problem with the arguments made to a
    call.
    """
    pass

class ICATInternalError(ICATError):
    """May be caused by network problems, database problems, GlassFish
    problems or bugs in ICAT.
    """
    pass

class ICATPrivilegesError(ICATError):
    """Indicates that the authorization rules have not matched your
    request.
    """<commit_msg>Python 2.6 does not support keyword arguments in str.encode().<commit_after>"""Exception handling.
"""

import sys
from collections import Mapping
import suds

__all__ = [
    # helper
    'stripCause', 
    # Exceptions thrown by the ICAT or IDS server
    'ICATError', 'ICATParameterError', 'ICATInternalError', 
    'ICATPrivilegesError', 'ICATNoObjectError', 'ICATObjectExistsError', 
    'ICATSessionError', 'ICATValidationError', 
    'IDSError', 'IDSBadRequestError', 'IDSDataNotOnlineError', 
    'IDSInsufficientPrivilegesError', 'IDSInsufficientStorageError', 
    'IDSInternalError', 'IDSNotFoundError', 'IDSNotImplementedError', 
    'translateError', 
    # Internal error
    'InternalError', 
    # icat.config
    'ConfigError', 
    # icat.query
    'QueryNullableOrderWarning', 
    # icat.client, icat.entity
    'ClientVersionWarning', 'ICATDeprecationWarning', 'VersionMethodError', 
    'SearchResultError', 'SearchAssertionError', 'DataConsistencyError', 
    # icat.ids
    'IDSResponseError', 
    # icat.icatcheck
    'GenealogyError',
    ]


# ======================== helper function =========================

def stripCause(e):
    """Try to suppress misleading context from an exception.

    `Exception Chaining and Embedded Tracebacks`_ has been introduced
    with Python 3.  Unfortunately the result is completely misleading
    most of the times.  Try to suppress the context from the exception
    traceback.  This works with Python 3.3 and newer, but has no
    effect with Python 3.1 and 3.2.

    .. _Exception Chaining and Embedded Tracebacks: http://legacy.python.org/dev/peps/pep-3134/
    """
    if hasattr(e, '__cause__'):
        e.__cause__ = None
    return e


# ========== Exceptions thrown by the ICAT or IDS server ===========

class ServerError(Exception):
    """Errors raised by either the ICAT or the IDS server.

    This is the common base class for ICATError and IDSError, it is
    not intented to be raised directly.
    """
    def __init__(self, error, status):
        """Expecept either a suds.WebFault or a Mapping with the keys 'code',
        'message', and 'offset'.
        """
        if isinstance(error, suds.WebFault):
            try:
                message = self._convertmsg(error.fault.faultstring)
            except AttributeError:
                message = self._convertmsg(str(error))
            super(ServerError, self).__init__(message)
            self.status = status
            self.message = message
            self.fault = error.fault
            self.document = error.document
            try:
                icatexception = error.fault.detail.IcatException
            except AttributeError:
                pass
            else:
                self.type = getattr(icatexception, 'type', None)
                self.offset = getattr(icatexception, 'offset', None)
                if self.offset is not None and self.offset < 0:
                    self.offset = None
        elif isinstance(error, Mapping):
            # Deliberately not fetching KeyError here.  Require the
            # field to be present.  Only 'offset' is optional.
            message = self._convertmsg(error['message'])
            super(ServerError, self).__init__(message)
            self.status = status
            self.message = message
            self.type = str(error['code'])
            self.offset = error.get('offset', None)
        else:
            raise TypeError("Invalid argument type '%s'." % type(error))

    def _convertmsg(self, msg):
        # msg may be a str, a suds.sax.text.Text instance, or (only
        # for Python 2) an unicode instance.  In Python 2, we must
        # convert it to a pure ascii string for Exception.  In Python
        # 3, we convert it to a str.  It may still contain non-ascii
        # chars, but this is ok for Exception in Python 3.
        if sys.version_info < (3, 0):
            return msg.encode('ascii', 'replace')
        else:
            return str(msg)


class ICATError(ServerError):
    """Base class for the errors raised by the ICAT server.
    """
    pass

class ICATParameterError(ICATError):
    """Generally indicates a problem with the arguments made to a
    call.
    """
    pass

class ICATInternalError(ICATError):
    """May be caused by network problems, database problems, GlassFish
    problems or bugs in ICAT.
    """
    pass

class ICATPrivilegesError(ICATError):
    """Indicates that the authorization rules have not matched your
    request.
    """
{'fraction_non_alphanumeric': 0.10406937958639093, 'fraction_numerical': 0.004225038914832111, 'mean_word_length': 2.53021978021978, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2709970', 'n_tokens_mistral': 2555, 'n_tokens_neox': 2416, 'n_words': 788}