Centralized Exception Handling using Middleware
Harshit Kalucha
AI Integration Engineer at First Advantage | PhD Scholar (CS) JIIT | DevOps | Data Science enthusiast | Software Developer| Blog Writer
Hello everyone, it's been a while since I last wrote an article. This piece aims to assist fellow developers by presenting an approach that goes beyond conventional blogging—it's a methodology I devised and implemented in a recent project.
In my role as a backend developer working with Python Django, my primary tasks revolved around developing and troubleshooting APIs. Given that the project wasn't built entirely from scratch, much of the development work involved creating new functionalities from the ground up. During this process, I noticed a recurring pattern where exception handling using try-catch blocks and input validation through conditional statements were implemented across all APIs.
With that, it came to my mind that we are just following the same structure of try except in all APIs. Most of the client response messages were also the same when specific exceptions were occurring, the only difference was that some of the APIs had some specific exceptions raised or handled.
This section was very common in all APIs, can't we create something that can centralize these processes, and the differences or the cases that are there in between the APIs can be put in a file base or db base structure so that API by API we can fetch from db or file and then this process can handle the case.
Let's dive deeper into my problem statement:
Imagine having to craft try-except blocks for each of the 100 APIs, along with validating request parameters to ensure keys are not null, contain valid values, and meet certain database-driven criteria. After much contemplation, I devised a centralized solution to address these challenges.
Middlewares
What are middlewares?
Middleware is like a mediator between different parts of a software system, helping them communicate and work together smoothly, similar to how sauce in a sandwich helps ingredients come together tastefully.
In the request-response cycle of middleware:
领英推荐
In short, middleware sits between the client request and server response, allowing for various processing steps to be applied to both the request and response
Here's how I incorporated middleware in my project:
To streamline exception handling, I leveraged middleware to manage exceptions across all APIs. Additionally, I created a JSON file housing custom exception messages tailored to specific exception classes encountered in different APIs.
Allow me to demonstrate:
{
"api_name_1": {
"ExceptionClass1": "Error message 1 for ExceptionClass1",
"ExceptionClass2": "Error message 2 for ExceptionClass2"
},
"api_name_2": {
"ExceptionClass3": "Error message 1 for ExceptionClass3"
}
}
This JSON structure was instrumental in delivering personalized error messages to clients upon encountering specific exception types.
import json
import logging
from django.http import JsonResponse
logger = logging.getLogger(__name__)
class ExceptionHandlingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
with open('error_messages.json', 'r') as f:
self.error_messages = json.load(f)
def __call__(self, request):
response = self.get_response(request)
return response
def process_exception(self, request, exception):
api_name = request.path
error_message = None
if api_name in self.error_messages:
exception_class = exception.__class__.__name__
if exception_class in self.error_messages[api_name]:
error_message = self.error_messages[api_name][exception_class]
logger.error(f"Exception: {exception_class}, Message: {exception}", exc_info=True)
else:
logger.error(f"Unhandled Exception: {exception_class}, Message: {exception}", exc_info=True)
if error_message:
return JsonResponse({'error': error_message}, status=500)
else:
# Send a generic error message to the client
return JsonResponse({'error': 'An error occurred. Please try again later.'}, status=500)
This middleware not only simplified exception handling but also offered the following benefits to clients:
In essence, adopting a centralized approach to exception handling is crucial for developing secure web applications with Django. By consolidating error management into centralized components, developers can streamline development, enhance code reusability, and increase the reliability and security of their applications. Whether you're crafting traditional web apps or RESTful APIs, harnessing Django's robust features for exception handling and input validation is key to delivering top software solutions. As developers dive deeper into the realm of web application development, the significance of efficient error management becomes increasingly apparent. By centralizing exception handling through middleware in Django projects, developers can not only streamline their workflow but also enhance the overall robustness and security of their applications.
“With Microsoft Copilot, it’s like pair programming but with an AI. ??” Follow for more details |?bSkilling https://www.bskilling.com/courses/Microsoft/clt2qu86q0001r8n9dnpbbdz7?id=clt2qu86q0001r8n9dnpbbdz7&category=Microsoft