-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy patherror.py
More file actions
116 lines (92 loc) · 3.5 KB
/
error.py
File metadata and controls
116 lines (92 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import sys
import json
import urllib
import socket
import logging
import urllib2
import traceback
from django.conf import settings
from .utils import from_dotted_path
from .app_settings import app_settings
logger = logging.getLogger(__name__)
class Error(dict):
def __init__(self, exc_type, exc_value, exc_traceback, ident):
tb = traceback.extract_tb(exc_traceback)
synopsis = traceback.format_exception_only(exc_type, exc_value)[-1]
self.update({
'ident': ident or '',
'server': socket.gethostname()[:100],
'synopsis': synopsis.strip()[:200],
'traceback': json.dumps(tb),
'apps': json.dumps(settings.INSTALLED_APPS),
'exc_type': exc_type.__name__,
'sys_path': json.dumps(sys.path),
})
def send(self):
url = app_settings.URL % '/errors'
logger.debug("Posting error to %s", url)
self._send(url, self, {'X-API-Key': app_settings.SECRET_KEY})
def _send(self, url, data, headers):
req = urllib2.Request(url, urllib.urlencode(data), headers)
try:
if not app_settings.IS_TEST:
urllib2.urlopen(req, timeout=app_settings.TIMEOUT) # pragma: no cover
except urllib2.HTTPError as e:
try:
# We try and print a descriptive message on the first line of
# the response
e.msg = '%s - %s' % (e.msg, e.read().splitlines()[0])
except IndexError:
logger.exception("Exception whilst reporting error to keyerror.com")
raise
class DjangoError(Error):
def __init__(self, request, *args, **kwargs):
super(DjangoError, self).__init__(*args, **kwargs)
self.update({
'url': request.build_absolute_uri(),
'type': 'django',
})
try:
self['user'] = json.dumps(self.get_user_info(request))
except Exception:
logger.exception("Exception whilst reporting error to keyerror.com")
def get_user_info(self, request):
# Don't depend on contrib.auth
if hasattr(request, 'user') and request.user.is_authenticated():
# Try and determine a reasonable default display name. We try not
# rely on username existing - this field is often removed.
display = request.user.get_full_name().strip() or \
getattr(request.user, 'username', '')
# Set defaults
user = {
'url': '',
'display': display,
'avatar_url': '',
'identifier': str(request.user.id),
'is_authenticated': True,
}
# Allow app to override
fn = from_dotted_path(app_settings.USER_INFO_CALLBACK)
user.update(fn(request))
return user
if hasattr(request, 'session') and request.session.session_key:
return {
'identifier': request.session.session_key,
'is_authenticated': False,
}
return {}
class MinimalDjangoError(Error):
"""
Like DjangoError, except doesn't require a request.
"""
def __init__(self, *args, **kwargs):
super(MinimalDjangoError, self).__init__(*args, **kwargs)
self.update({
'type': 'django',
})
class QueueError(Error):
def __init__(self, *args, **kwargs):
super(QueueError, self).__init__(*args, **kwargs)
self.update({
'type': 'queue',
})