# Imports
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.http import HttpResponse, HttpResponseServerError
from django.template import loader
from django.views.debug import ExceptionReporter
import socket
# Exports
__all__ = (
"ErrorHandler",
)
# Classes
[docs]class ErrorHandler(object):
"""Base class for creating an error handler."""
required_settings = list()
traceback = __import__('traceback')
[docs] def __init__(self):
"""Initialize the context and check required settings."""
self.context = dict()
message = "The following settings are required for the %s backend: %s"
for required_setting in self.required_settings:
if not hasattr(settings, required_setting):
raise ImproperlyConfigured(message % (self.__class__.__name__, ", ".join(self.required_settings)))
def __call__(self, report, context=None):
"""Process the exception.
:param report: An exception reporter instance for the current exception(s).
:type report: django.views.debug.ExceptionReporter
:param context: Additional context, especially from any previous error handlers.
:type context: dict
:rtype: dict | HttpResponse | HttpResponseRedirect | HttpResponseServerError
"""
# Add report data to the context.
self.context.update(report.get_traceback_data())
# Additional context may have been received from previous handlers.
if context is not None:
self.context.update(context)
# Allow the handler to do additional work.
result = self.handle(report)
# Return the result if it is not None.
if result is not None:
return result
# Otherwise return an error response.
template = loader.get_template("500.html")
content = template.render(self.context)
return HttpResponseServerError(content)
# noinspection PyUnusedLocal,PyMethodMayBeStatic
[docs] def handle(self, report):
"""Provide additional handling of the exception.
:param report: An exception reporter instance for the current exception(s).
:type report: django.views.debug.ExceptionReporter
:rtype: dict | HttpResponse | None
"""
return None
def _parse_template(self, path):
"""Parse a given template using the current context.
:param path: The path or name of template.
:type path: str
:rtype: str
"""
return loader.render_to_string(path, self.context)
'''
class ErrorHandler(object):
"""Base class for creating an error handler."""
required_settings = list()
traceback = __import__('traceback')
def __init__(self):
"""Initialize the context and check required settings."""
self.context = dict()
message = "The following settings are required for the %s backend: %s"
for required_setting in self.required_settings:
if not hasattr(settings, required_setting):
raise ImproperlyConfigured(message % (self.__class__.__name__, ", ".join(self.required_settings)))
def __call__(self, request, exception, info, context=None):
"""Process the exception.
:param report: An exception reporter instance for the current exception(s).
:type report: django.views.debug.ExceptionReporter
:param request: The current request instance.
:param exception: The exception being handled.
:param info: The ``sys.exc_info()`` of the exception.
:param context: Additional context, especially from any previous error handlers.
:type context: dict
:rtype: HttpResponse | HttpResponseRedirect | HttpResponseServerError
"""
# Get the traceback. This produces a list where format_exc() produces a string.
traceback = self.traceback.format_exception(*info)
# Add data to the context.
# self.context.update(report.get_traceback_data())
self.context.update(self.get_data(request, exception, traceback))
if context is not None:
self.context.update(context)
# Allow the handler to do additional work.
result = self.handle(request, exception, traceback)
# Return the result if it is itself a response.
if isinstance(result, HttpResponse):
return result
# Otherwise return an error response.
template = loader.get_template("500.html")
content = template.render(self.context)
return HttpResponseServerError(content)
# noinspection PyUnusedLocal,PyMethodMayBeStatic
def get_data(self, request, exception, traceback):
"""Get the data to be included in the response context.
:param request: The current request instance.
:param exception: The exception being handled.
:param traceback: The current traceback.
:rtype: dict
"""
if isinstance(exception, Exception):
name = exception.__class__.__name__
else:
name = exception.__name__
data = {
'GET': request.GET,
'POST': request.POST,
'SERVER_HOSTNAME': socket.gethostname(),
'error_name': name,
'request_path': request.get_full_path(),
'traceback': traceback,
}
data.update(request.META)
return data
# noinspection PyUnusedLocal,PyMethodMayBeStatic
def handle(self, request, exception, traceback):
"""Provide additional handling of the exception.
:param request: The current request instance.
:param exception: The exception being handled.
:param traceback: The current traceback (iterable).
:rtype: HttpResponse | None
"""
return None
'''