Skip to content

Commit e396bc0

Browse files
committed
add test for middleware exception handling
1 parent 417caf5 commit e396bc0

File tree

4 files changed

+535
-0
lines changed

4 files changed

+535
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
from asgiref.sync import iscoroutinefunction, markcoroutinefunction
2+
3+
from django.http import Http404, HttpResponse
4+
from django.template import engines
5+
from django.template.response import TemplateResponse
6+
from django.utils.decorators import (
7+
async_only_middleware,
8+
sync_and_async_middleware,
9+
)
10+
11+
log = []
12+
13+
14+
class BaseMiddleware:
15+
async_capable = True
16+
sync_capable = False
17+
18+
def __init__(self, get_response):
19+
self.get_response = get_response
20+
if iscoroutinefunction(self.get_response):
21+
markcoroutinefunction(self)
22+
23+
async def __call__(self, request):
24+
return await self.get_response(request)
25+
26+
27+
class ProcessExceptionMiddleware(BaseMiddleware):
28+
def process_exception(self, request, exception):
29+
return HttpResponse("Exception caught")
30+
31+
32+
@async_only_middleware
33+
class AsyncProcessExceptionMiddleware(BaseMiddleware):
34+
async def process_exception(self, request, exception):
35+
return HttpResponse("Exception caught")
36+
37+
38+
class ProcessExceptionLogMiddleware(BaseMiddleware):
39+
def process_exception(self, request, exception):
40+
log.append("process-exception")
41+
42+
43+
class ProcessExceptionExcMiddleware(BaseMiddleware):
44+
def process_exception(self, request, exception):
45+
raise Exception("from process-exception")
46+
47+
48+
class ProcessViewMiddleware(BaseMiddleware):
49+
def process_view(self, request, view_func, view_args, view_kwargs):
50+
return HttpResponse("Processed view %s" % view_func.__name__)
51+
52+
53+
@async_only_middleware
54+
class AsyncProcessViewMiddleware(BaseMiddleware):
55+
async def process_view(self, request, view_func, view_args, view_kwargs):
56+
return HttpResponse("Processed view %s" % view_func.__name__)
57+
58+
59+
class ProcessViewNoneMiddleware(BaseMiddleware):
60+
def process_view(self, request, view_func, view_args, view_kwargs):
61+
log.append("processed view %s" % view_func.__name__)
62+
return None
63+
64+
65+
class ProcessViewTemplateResponseMiddleware(BaseMiddleware):
66+
def process_view(self, request, view_func, view_args, view_kwargs):
67+
template = engines["django"].from_string(
68+
"Processed view {{ view }}{% for m in mw %}\n{{ m }}{% endfor %}"
69+
)
70+
return TemplateResponse(
71+
request,
72+
template,
73+
{"mw": [self.__class__.__name__], "view": view_func.__name__},
74+
)
75+
76+
77+
class TemplateResponseMiddleware(BaseMiddleware):
78+
def process_template_response(self, request, response):
79+
response.context_data["mw"].append(self.__class__.__name__)
80+
return response
81+
82+
83+
@async_only_middleware
84+
class AsyncTemplateResponseMiddleware(BaseMiddleware):
85+
async def process_template_response(self, request, response):
86+
response.context_data["mw"].append(self.__class__.__name__)
87+
return response
88+
89+
90+
class LogMiddleware(BaseMiddleware):
91+
async def __call__(self, request):
92+
response = await self.get_response(request)
93+
log.append((response.status_code, response.content))
94+
return response
95+
96+
97+
class NoTemplateResponseMiddleware(BaseMiddleware):
98+
def process_template_response(self, request, response):
99+
return None
100+
101+
102+
@async_only_middleware
103+
class AsyncNoTemplateResponseMiddleware(BaseMiddleware):
104+
async def process_template_response(self, request, response):
105+
return None
106+
107+
108+
class NotFoundMiddleware(BaseMiddleware):
109+
async def __call__(self, request):
110+
raise Http404("not found")
111+
112+
113+
@async_only_middleware
114+
def async_payment_middleware(get_response):
115+
async def middleware(request):
116+
response = await get_response(request)
117+
response.status_code = 402
118+
return response
119+
120+
return middleware
121+
122+
123+
@sync_and_async_middleware
124+
class SyncAndAsyncMiddleware(BaseMiddleware):
125+
pass
126+
127+
128+
class NotSyncOrAsyncMiddleware(BaseMiddleware):
129+
"""Middleware that is deliberately neither sync or async."""
130+
131+
sync_capable = False
132+
async_capable = False
133+
134+
async def __call__(self, request):
135+
return await self.get_response(request)

0 commit comments

Comments
 (0)