Wrap the given get_response callable in exception-to-response conversion. All exceptions will be converted. All known 4xx exceptions (Http404, PermissionDenied, MultiPartParserError, SuspiciousOperation) will be converted to the appropriate response, and all other exceptions will b
(get_response)
| 23 | |
| 24 | |
| 25 | def convert_exception_to_response(get_response): |
| 26 | """ |
| 27 | Wrap the given get_response callable in exception-to-response conversion. |
| 28 | |
| 29 | All exceptions will be converted. All known 4xx exceptions (Http404, |
| 30 | PermissionDenied, MultiPartParserError, SuspiciousOperation) will be |
| 31 | converted to the appropriate response, and all other exceptions will be |
| 32 | converted to 500 responses. |
| 33 | |
| 34 | This decorator is automatically applied to all middleware to ensure that |
| 35 | no middleware leaks an exception and that the next middleware in the stack |
| 36 | can rely on getting a response instead of an exception. |
| 37 | """ |
| 38 | if iscoroutinefunction(get_response): |
| 39 | |
| 40 | @wraps(get_response) |
| 41 | async def inner(request): |
| 42 | try: |
| 43 | response = await get_response(request) |
| 44 | except Exception as exc: |
| 45 | response = await sync_to_async( |
| 46 | response_for_exception, thread_sensitive=False |
| 47 | )(request, exc) |
| 48 | return response |
| 49 | |
| 50 | return inner |
| 51 | else: |
| 52 | |
| 53 | @wraps(get_response) |
| 54 | def inner(request): |
| 55 | try: |
| 56 | response = get_response(request) |
| 57 | except Exception as exc: |
| 58 | response = response_for_exception(request, exc) |
| 59 | return response |
| 60 | |
| 61 | return inner |
| 62 | |
| 63 | |
| 64 | def response_for_exception(request, exc): |