diff --git a/error_tracker/__init__.py b/error_tracker/__init__.py index 0580b9f..db06f35 100644 --- a/error_tracker/__init__.py +++ b/error_tracker/__init__.py @@ -6,7 +6,7 @@ # :license: BSD-3-Clause # -__version__ = '1.1.5' +__version__ = '1.1.6' __author__ = 'Sonu Kumar' __email__ = 'sonunitw12@gmail.com' diff --git a/error_tracker/django/utils.py b/error_tracker/django/utils.py index 40d016d..4bc7430 100644 --- a/error_tracker/django/utils.py +++ b/error_tracker/django/utils.py @@ -7,6 +7,7 @@ # import re +import json from django.http import RawPostDataException @@ -36,11 +37,13 @@ def _get_form_data(request): except RawPostDataException: pass if body is not None: - from rest_framework.request import Request - if isinstance(body, Request): - form = body.data - elif len(body) > 0: - import json + try: + from rest_framework.request import Request + if isinstance(body, Request): + form = body.data + except ImportError: + pass + if len(form) == 0 and len(body) > 0: try: form = json.loads(body, encoding="UTF-8") except Exception: diff --git a/error_tracker/libs/exception_formatter.py b/error_tracker/libs/exception_formatter.py index ae56d25..4c54416 100755 --- a/error_tracker/libs/exception_formatter.py +++ b/error_tracker/libs/exception_formatter.py @@ -2,7 +2,7 @@ # # Exception formatter that captures frame details in string format. # -# :copyright: 2019 Sonu Kumar +# :copyright: 2020 Sonu Kumar # :license: BSD-3-Clause # @@ -11,8 +11,6 @@ import sys import traceback -from django.http import QueryDict - try: import builtins except ImportError: @@ -24,7 +22,22 @@ import re import types -from werkzeug.datastructures import ImmutableMultiDict + + +def convert_if_possible(x): + try: + from werkzeug.datastructures import ImmutableMultiDict + if type(x) == ImmutableMultiDict: + return "ImmutableMultiDict({%s})", x.to_dict(flat=False) + except ImportError: + pass + try: + from django.http import QueryDict + if type(x) == QueryDict: + return "QueryDict({%s})", x.dict() + except ImportError: + pass + return None, None def format_frame(x, max_elements, max_string, max_recursion, masking=None): @@ -71,38 +84,34 @@ def _it_to_string(fmt, it, per_element=_per_element): if x is builtins.__dict__: return "" - elif type(x) == dict: + if type(x) == dict: return _it_to_string("{%s}", sorted(x.items()), per_element=_per_dict_element) - elif type(x) == list: + if type(x) == list: return _it_to_string("[%s]", x) - elif type(x) == tuple: + if type(x) == tuple: return _it_to_string("(%s)" if len(x) != 1 or max_recursion <= 0 or max_elements <= 0 else "(%s,)", x) - elif type(x) == set: + if type(x) == set: return _it_to_string("set([%s])", sorted(x)) - elif type(x) == frozenset: + if type(x) == frozenset: return _it_to_string("frozenset([%s])", sorted(x)) - elif isinstance(x, six.string_types) and max_string < len(x): + if isinstance(x, six.string_types) and max_string < len(x): return repr(x[:max_string] + "...") - elif type(x) == ImmutableMultiDict: - x = x.to_dict(flat=False) - return _it_to_string("ImmutableMultiDict({%s})", sorted(x.items()), - per_element=_per_dict_element) - elif type(x) == QueryDict: - x = x.dict() - return _it_to_string("QueryDict({%s})", sorted(x.items()), + + converted, x = convert_if_possible(x) + if converted is not None: + return _it_to_string(converted, sorted(x.items()), per_element=_per_dict_element) - else: - try: - if issubclass(x, dict): - x = dict(x) - return _it_to_string("Dict({%s})", sorted(x.items()), - per_element=_per_dict_element) - except TypeError: - pass - return repr(x) + try: + if issubclass(x, dict): + x = dict(x) + return _it_to_string("Dict({%s})", sorted(x.items()), + per_element=_per_dict_element) + except TypeError: + pass + return repr(x) def can_be_skipped(key, value): diff --git a/error_tracker/libs/utils.py b/error_tracker/libs/utils.py index 3983712..3aceace 100644 --- a/error_tracker/libs/utils.py +++ b/error_tracker/libs/utils.py @@ -10,7 +10,6 @@ import warnings from hashlib import sha256 import six -from django.utils.module_loading import import_string from error_tracker.libs.exception_formatter import format_exception from error_tracker.libs.mixins import MaskingMixin @@ -75,6 +74,7 @@ def get_class_from_path(module_path, super_class, raise_exception=True, :param warning_message: any warning message :return: imported class """ + from django.utils.module_loading import import_string try: cls = import_string(module_path) cls_fields = cls.__dict__.keys() diff --git a/setup.py b/setup.py index d5368b1..0347617 100755 --- a/setup.py +++ b/setup.py @@ -42,15 +42,20 @@ def grep(attrname): zip_safe=False, platforms='any', install_requires=[ - "Flask", - "Django", - "Flask-SQLAlchemy", "six", - "djangorestframework" ], + extras_require={ + "Django": ["Django"], + "DRF": ["djangorestframework"], + "Flask": ["Flask", "Flask-SQLAlchemy"], + }, tests_require=[ "Flask-Mail", 'pyquery' + "Django", + "djangorestframework", + "Flask", + "Flask-SQLAlchemy" ], classifiers=[ 'Development Status :: 5 - Production/Stable',