I am writing an API function using Django Rest Framework where it accesses many resources like AWS, Database, External APIs etc., I want the API execution to stop if it fails in any of the steps and return an appropriate response.
I initially used ValueError to raise exceptions manually when something failed, but this resulted in traceback being printed in logs for manually raised exceptions, and the logs became messy.
Later, I used separate except statement for "ValueError" and "Exception" but this led to traceback not being printed for naturally occuring (not manually raised) exceptions and debugging them were hard.
So I created a custom exception which takes an error code, and an error message like below.
class CustomException(Exception):
def __init__(self, status, msg):
self.status = status
self.message = msg
super().__init__(self.message + ': ' + str(self.status))
def __str__(self):
return 'ErrorCode: ' + str(self.status) + ' ErrorMessage:' + str(self.message)
And I came up with the below code structure for the API function,
def place_order(request):
err_msg = 'Problem in placing order. Please contact us'
try:
response = get_product_details_from_db()
if response.status == 0:
err_msg = 'Failed to get product details from DB'
raise CustomException(0, err_msg)
# Do something...
response = access_aws_s3_files()
if response.status == 0:
err_msg = 'Failed trying to access s3'
raise CustomException(0, err_msg)
# Do something...
response = call_external_api()
if response.status == 0:
err_msg = 'Failed in accessing external API'
raise CustomException(0, err_msg)
# Do something...
response_data = {
'status': 1,
'order_id': '1235'
}
except CustomException as e:
response_data = {
'status': e.status,
'error_message': e.message
}
except Exception as e:
traceback.print_exc()
print(e)
response_data = {
'status': 0,
'error_message': err_msg
}
return Response(data=json.dumps(response_data), status=status.HTTP_200_OK)
Is this the standard way of handling such things? Is there any better/alternative way we can handle this ?