forked from sonus21/error-tracker
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmiddleware.py
More file actions
131 lines (111 loc) · 4.68 KB
/
middleware.py
File metadata and controls
131 lines (111 loc) · 4.68 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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# -*- coding: utf-8 -*-
#
# Django error tracker middleware responsible for recording exception
#
# :copyright: 2020 Sonu Kumar
# :license: BSD-3-Clause
#
from error_tracker.django import get_masking_module, get_context_builder, get_ticketing_module, \
get_exception_model, get_notification_module, APP_ERROR_SUBJECT_PREFIX, APP_ERROR_EMAIL_SENDER, \
APP_ERROR_RECIPIENT_EMAIL, TRACK_ALL_EXCEPTIONS, APP_ERROR_NOTIFICATION_ONCE, \
APP_ERROR_TICKET_ONCE
from error_tracker.libs.utils import get_exception_name, get_context_detail, get_notification_subject
model = get_exception_model()
ticketing = get_ticketing_module()
masking = get_masking_module()
notifier = get_notification_module()
context_builder = get_context_builder()
# noinspection PyMethodMayBeStatic
class ErrorTracker(object):
"""
ErrorTracker class, this is responsible for capturing exceptions and
sending notifications and taking other actions,
"""
@staticmethod
def _send_notification(request, message, exception, error):
"""
Send notification to the list of entities or call the specific methods
:param request: request object
:param message: message having frame details
:param exception: exception that's triggered
:param error: error model object
:return: None
"""
if notifier is None:
return
if request is not None:
method = request.method
url = request.get_full_path()
else:
method = ""
url = ""
subject = get_notification_subject(APP_ERROR_SUBJECT_PREFIX,
method, url, exception)
notifier.notify(request,
error,
email_subject=subject,
email_body=message,
from_email=APP_ERROR_EMAIL_SENDER,
recipient_list=APP_ERROR_RECIPIENT_EMAIL)
@staticmethod
def _raise_ticket(request, error):
if ticketing is None:
return
ticketing.raise_ticket(request, error)
@staticmethod
def _post_process(request, frame_str, frames, error):
send_notification = True
raise_ticket = True
if request is not None:
message = ('URL: %s' % request.path) + '\n\n'
else:
message = ""
message += frame_str
if APP_ERROR_NOTIFICATION_ONCE is True and error.notification_sent is True:
send_notification = False
if APP_ERROR_TICKET_ONCE is True and error.ticket_raised is True:
raise_ticket = False
if send_notification:
ErrorTracker._send_notification(request, message, frames[-1][:-1], error)
if raise_ticket:
ErrorTracker._raise_ticket(request, error)
def capture_exception(self, request=None, exception=None, additional_context=None):
"""
Record the exception details and do post processing actions. this method can be used to track any exceptions,
even those are being excepted using try/except block.
:param request: request object
:param exception: what type of exception has occurred
:param additional_context: any additional context
:return: None
"""
if request is not None:
path = request.path
host = request.META.get('HTTP_HOST', '')
method = request.method
else:
path = ""
host = ""
method = ""
ty, frames, frame_str, traceback_str, rhash, request_data = \
get_context_detail(request, masking, context_builder,
additional_context=additional_context)
error = model.create_or_update_entity(rhash, host, path, method,
str(request_data),
get_exception_name(ty),
traceback_str)
ErrorTracker._post_process(request, frame_str, frames, error)
class ExceptionTrackerMiddleWare(ErrorTracker):
"""
Error tracker middleware that's invoked in the case of exception occurs,
this should be placed at the end of Middleware lists
"""
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
return self.get_response(request)
def process_exception(self, request, exception):
if exception is None and not TRACK_ALL_EXCEPTIONS:
return
self.capture_exception(request, exception)
# use this object to track errors in the case of custom failures, where try/except is used
error_tracker = ErrorTracker()