<commit_before>"""Errors

This module implements a set of standard HTTP Errors.
"""
import json

try:
    from html import escape
except ImportError:
    from cgi import escape  # Deprecated since version 3.2


try:
    from urllib.parse import urljoin as _urljoin
except ImportError:
    from urlparse import urljoin as _urljoin  # NOQA

from circuits import Event

from ..six import string_types
from .constants import SERVER_URL, SERVER_VERSION, POWERED_BY
from .constants import DEFAULT_ERROR_MESSAGE, HTTP_STATUS_CODES


class httperror(Event):

    """An event for signaling an HTTP error"""

    code = 500
    description = ""

    def __init__(self, request, response, code=None, **kwargs):
        """
        The constructor creates a new instance and modifies the *response*
        argument to reflect the error.
        """
        super(httperror, self).__init__(request, response, code, **kwargs)

        # Override HTTPError subclasses
        self.name = "httperror"

        self.request = request
        self.response = response

        if code is not None:
            self.code = code

        self.error = kwargs.get("error", None)

        self.description = kwargs.get(
            "description", getattr(self.__class__, "description", "")
        )

        if self.error is not None:
            self.traceback = "ERROR: (%s) %s\n%s" % (
                self.error[0], self.error[1], "".join(self.error[2])
            )
        else:
            self.traceback = ""

        self.response.close = True
        self.response.status = self.code

        powered_by = POWERED_BY % ({
            "url": SERVER_URL,
            "version": SERVER_VERSION
        }) if getattr(request.server, 'display_banner', False) else ""

        self.data = {
            "code": self.code,
            "name": HTTP_STATUS_CODES.get(self.code, "???"),
            "description": self.description,
            "traceback": escape(self.traceback),
            "powered_by": powered_by
        }

    def sanitize(self):
        if self.code != 201 and not (299 < self.code < 400):
            if "Location" in self.response.headers:
                del self.response.headers["Location"]

    def __str__(self):
        self.sanitize()<commit_msg>Make use of the traceback module to format the exception<commit_after>"""Errors

This module implements a set of standard HTTP Errors.
"""
import json
import traceback

try:
    from html import escape
except ImportError:
    from cgi import escape  # Deprecated since version 3.2

try:
    from urllib.parse import urljoin as _urljoin
except ImportError:
    from urlparse import urljoin as _urljoin  # NOQA

from circuits import Event

from ..six import string_types
from .constants import SERVER_URL, SERVER_VERSION, POWERED_BY
from .constants import DEFAULT_ERROR_MESSAGE, HTTP_STATUS_CODES


class httperror(Event):

    """An event for signaling an HTTP error"""

    code = 500
    description = ""

    def __init__(self, request, response, code=None, **kwargs):
        """
        The constructor creates a new instance and modifies the *response*
        argument to reflect the error.
        """
        super(httperror, self).__init__(request, response, code, **kwargs)

        # Override HTTPError subclasses
        self.name = "httperror"

        self.request = request
        self.response = response

        if code is not None:
            self.code = code

        self.error = kwargs.get("error", None)

        self.description = kwargs.get(
            "description", getattr(self.__class__, "description", "")
        )

        if self.error is not None:
            #self.traceback = "ERROR: (%s) %s\n%s" % (
            #    self.error[0], self.error[1], "".join(self.error[2])
            #)
            self.traceback = "\n".join(traceback.format_exception(*self.error))
        else:
            self.traceback = ""

        self.response.close = True
        self.response.status = self.code

        powered_by = POWERED_BY % ({
            "url": SERVER_URL,
            "version": SERVER_VERSION
        }) if getattr(request.server, 'display_banner', False) else ""

        self.data = {
            "code": self.code,
            "name": HTTP_STATUS_CODES.get(self.code, "???"),
            "description": self.description,
            "traceback": escape(self.traceback),
            "powered_by": powered_by
        }

    def sanitize(self):
        if self.code != 201 and not (299 < self.code < 400):
            if "Location" in self.response.headers:
                del self.response.headers["Location"]

    def __str__(self):
        self.sanitize()
{'fraction_non_alphanumeric': 0.1055793991416309, 'fraction_numerical': 0.007296137339055794, 'mean_word_length': 2.257162823200559, 'pattern_counts': {'":': 14, '<': 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': '1839347', 'n_tokens_mistral': 1358, 'n_tokens_neox': 1311, 'n_words': 378}