I want to log any type of error that occurs during an API request in Django Rest Framework into a CSV file, including the error message along with additional details like username, user ip, url, etc. I also want to capture errors that occur before reaching the view (e.g., errors related to JWT). I tried using middleware for this, but the issue was that some responses were not rendered correctly, and even after manually rendering, they still resulted in errors. I would appreciate it if you could suggest a solution.
The code below is the middleware I tried to use. I don't have an issue with logging errors that occur inside the view because if I only wanted to log errors within the view, I could use decorators or create a custom APIView. However, what I'm looking for is a way to log any type of error, even those that occur outside the view.
class ErrorLogMiddleware: def __init__(self, get_response): self.get_response = get_response self.filename = settings.ERROR_LOG_PATH self.fieldnames = ["Username", "IP", "User Agent", "Date/Time", "Time Interval", "Query", "Message", "URL"] def __call__(self, request): if not exists(self.filename): with open(self.filename, "a", newline="", encoding="utf-8") as csvfile: writer = DictWriter(csvfile, fieldnames=self.fieldnames) writer.writeheader() before = time() try: response = self.get_response(request) if response.status_code != 200: if hasattr(response, "render"): if not response.is_rendered: response.render() error = None if hasattr(response, "data"): error = response.data else: html_content = response.content.decode("utf-8") error = html_content.split("</title>")[0].split("<title>")[1] self.submit_error(request, before, error) return response except Exception as e: self.submit_error(request, before, e) return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) def submit_error(self, request, before, error): after = time() query = "" for dic in connection.queries: query += f"{dic['sql']}\n" new_error_log = { "Username": request.user.username, "IP": get_user_ip(request), "User Agent": request.META.get("HTTP_USER_AGENT"), "Date/Time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "Time Interval": after - before, "Query": query, "Message": str(error), "URL": request.get_full_path() } with open(self.filename, "a", newline="", encoding="utf-8") as csvfile: writer = DictWriter(csvfile, fieldnames=self.fieldnames) writer.writerow(new_error_log) error: The response content must be rendered before it can be accessed