From b19f69c41f3a2a81e1ed57b85baee0f874aae509 Mon Sep 17 00:00:00 2001 From: Jerome Celle Date: Wed, 20 Nov 2019 09:17:09 +0100 Subject: [PATCH] Add detail in paysafe error for the front --- retirement/serializers.py | 21 ++++++---- retirement/tests/tests_viewset_Reservation.py | 4 +- retirement/views.py | 2 + store/exceptions.py | 5 ++- store/serializers.py | 12 ++++-- store/services.py | 39 ++++++++++++------- store/tests/tests_viewset_CustomPayment.py | 8 +++- store/tests/tests_viewset_Order.py | 16 ++++++-- store/views.py | 5 ++- 9 files changed, 78 insertions(+), 34 deletions(-) diff --git a/retirement/serializers.py b/retirement/serializers.py index c4fb0322..99482fc3 100644 --- a/retirement/serializers.py +++ b/retirement/serializers.py @@ -589,7 +589,8 @@ def update(self, instance, validated_data): ) except PaymentAPIError as err: raise serializers.ValidationError({ - 'message': err + 'message': err, + 'detail': err.detail }) # Create local profile profile = PaymentProfile.objects.create( @@ -660,10 +661,12 @@ def update(self, instance, validated_data): 'non_field_errors': [_( "The order has not been charged yet. " "Try again later." - )] + )], + 'detail': err.detail }) raise serializers.ValidationError({ - 'message': str(err) + 'message': str(err), + 'detail': err.detail }) if payment_token and int(amount): @@ -676,7 +679,8 @@ def update(self, instance, validated_data): ) except PaymentAPIError as err: raise serializers.ValidationError({ - 'message': err + 'message': err, + 'detail': err.detail }) elif single_use_token and int(amount): @@ -693,7 +697,8 @@ def update(self, instance, validated_data): ) except PaymentAPIError as err: raise serializers.ValidationError({ - 'message': err + 'message': err, + 'detail': err.detail }) charge_res_content = charge_response.json() order.authorization_id = charge_res_content['id'] @@ -738,10 +743,12 @@ def update(self, instance, validated_data): 'non_field_errors': [_( "The order has not been charged yet. " "Try again later." - )] + )], + 'detail': err.detail }) raise serializers.ValidationError({ - 'message': str(err) + 'message': str(err), + 'detail': err.detail }) new_retreat = retreat diff --git a/retirement/tests/tests_viewset_Reservation.py b/retirement/tests/tests_viewset_Reservation.py index 3e36f61d..e6278b65 100644 --- a/retirement/tests/tests_viewset_Reservation.py +++ b/retirement/tests/tests_viewset_Reservation.py @@ -1150,7 +1150,9 @@ def test_delete_refund_too_fast(self): ] } - self.assertEqual(json.loads(response.content), content) + self.assertEqual( + json.loads(response.content).get('non_field_errors'), + content.get('non_field_errors')) self.reservation.refresh_from_db() diff --git a/retirement/views.py b/retirement/views.py index c8a0bf77..92f578ef 100644 --- a/retirement/views.py +++ b/retirement/views.py @@ -413,6 +413,7 @@ def destroy(self, request, *args, **kwargs): "The order has not been charged yet. Try " "again later." )], + 'detail': err.detail }) raise rest_framework_serializers.ValidationError( { @@ -421,6 +422,7 @@ def destroy(self, request, *args, **kwargs): "An error occured with the payment system." " Please try again later." )], + 'detail': err.detail } ) instance.cancelation_action = 'R' diff --git a/store/exceptions.py b/store/exceptions.py index 9143375b..ad504f1b 100644 --- a/store/exceptions.py +++ b/store/exceptions.py @@ -2,4 +2,7 @@ class PaymentAPIError(Exception): """ Raised when a payment related action fails. """ - pass + def __init__(self, error, detail): + + super(PaymentAPIError, self).__init__(error) + self.detail = detail diff --git a/store/serializers.py b/store/serializers.py index 97f5f3a3..d4e5a88a 100644 --- a/store/serializers.py +++ b/store/serializers.py @@ -281,7 +281,8 @@ def create(self, validated_data): ) except PaymentAPIError as err: raise serializers.ValidationError({ - 'non_field_errors': [err] + 'non_field_errors': [err], + 'detail': err.detail }) charge_res_content = charge_response.json() @@ -572,7 +573,8 @@ def create(self, validated_data): ) except PaymentAPIError as err: raise serializers.ValidationError({ - 'non_field_errors': [err] + 'non_field_errors': [err], + 'detail': err.detail }) # Create local profile profile = PaymentProfile.objects.create( @@ -797,7 +799,8 @@ def create(self, validated_data): ) except PaymentAPIError as err: raise serializers.ValidationError({ - 'non_field_errors': [err] + 'non_field_errors': [err], + 'detail': err.detail }) elif need_transaction and single_use_token and int(amount): @@ -814,7 +817,8 @@ def create(self, validated_data): ) except PaymentAPIError as err: raise serializers.ValidationError({ - 'non_field_errors': [err] + 'non_field_errors': [err], + 'detail': err.detail }) elif (membership_orderlines or package_orderlines diff --git a/store/services.py b/store/services.py index cae6377e..a09c9ba1 100644 --- a/store/services.py +++ b/store/services.py @@ -98,8 +98,9 @@ def manage_paysafe_error(err, additional_data): + content_dict = json.loads(err.response.content) try: - err_code = json.loads(err.response.content)['error']['code'] + err_code = content_dict['error']['code'] Log.error( source='PAYSAFE', @@ -109,7 +110,10 @@ def manage_paysafe_error(err, additional_data): ) if err_code in PAYSAFE_EXCEPTION: - raise PaymentAPIError(PAYSAFE_EXCEPTION[err_code]) + raise PaymentAPIError( + error=PAYSAFE_EXCEPTION[err_code], + detail=content_dict + ) except json.decoder.JSONDecodeError as err: print(err.response) @@ -119,7 +123,10 @@ def manage_paysafe_error(err, additional_data): message=err, additional_data=json.dumps(additional_data) ) - raise PaymentAPIError(PAYSAFE_EXCEPTION['unknown']) + raise PaymentAPIError( + error=PAYSAFE_EXCEPTION['unknown'], + detail=content_dict + ) def charge_payment(amount, payment_token, reference_number): @@ -160,10 +167,10 @@ def charge_payment(amount, payment_token, reference_number): r.raise_for_status() except requests.exceptions.HTTPError as err: manage_paysafe_error(err, { - 'amount': amount, - 'payment_token': payment_token, - 'reference_number': reference_number - }) + 'amount': amount, + 'payment_token': payment_token, + 'reference_number': reference_number + }) return r @@ -345,12 +352,12 @@ def create_external_card(profile_id, single_use_token): ) r.raise_for_status() except requests.exceptions.HTTPError as err: - err = json.loads(err.response.content) - err_code = err['error']['code'] + content_dict = json.loads(err.response.content) + err_code = content_dict['error']['code'] if err_code == "7503": try: r = get_external_card( - err['links'][0]['href'].split("/")[-1] + content_dict['links'][0]['href'].split("/")[-1] ) card_data = json.loads(r.content) delete_external_card(profile_id, card_data['id']) @@ -366,11 +373,15 @@ def create_external_card(profile_id, single_use_token): return r except requests.exceptions.HTTPError as err: if err_code in PAYSAFE_EXCEPTION: - raise PaymentAPIError(PAYSAFE_EXCEPTION[err_code]) - raise PaymentAPIError(PAYSAFE_EXCEPTION['unknown']) + raise PaymentAPIError(PAYSAFE_EXCEPTION[err_code], + detail=content_dict) + raise PaymentAPIError(PAYSAFE_EXCEPTION['unknown'], + detail=content_dict) if err_code in PAYSAFE_EXCEPTION: - raise PaymentAPIError(PAYSAFE_EXCEPTION[err_code]) - raise PaymentAPIError(PAYSAFE_EXCEPTION['unknown']) + raise PaymentAPIError(PAYSAFE_EXCEPTION[err_code], + detail=content_dict) + raise PaymentAPIError(PAYSAFE_EXCEPTION['unknown'], + detail=content_dict) return r diff --git a/store/tests/tests_viewset_CustomPayment.py b/store/tests/tests_viewset_CustomPayment.py index c80d3c23..49982e6c 100644 --- a/store/tests/tests_viewset_CustomPayment.py +++ b/store/tests/tests_viewset_CustomPayment.py @@ -157,7 +157,9 @@ def test_create_with_invalid_single_use_token(self): ] } - self.assertEqual(json.loads(response.content), content) + self.assertEqual( + json.loads(response.content).get('non_field_errors'), + content.get('non_field_errors')) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) @@ -230,7 +232,9 @@ def test_create_payment_issue(self): ] } - self.assertEqual(json.loads(response.content), content) + self.assertEqual( + json.loads(response.content).get('non_field_errors'), + content.get('non_field_errors')) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) diff --git a/store/tests/tests_viewset_Order.py b/store/tests/tests_viewset_Order.py index 07c2d434..3039fe64 100644 --- a/store/tests/tests_viewset_Order.py +++ b/store/tests/tests_viewset_Order.py @@ -1783,7 +1783,9 @@ def test_create_with_invalid_payment_token(self): ] } - self.assertEqual(json.loads(response.content), content) + self.assertEqual( + json.loads(response.content).get('non_field_errors'), + content.get('non_field_errors')) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) @@ -2030,7 +2032,9 @@ def test_create_with_invalid_single_use_token(self): ] } - self.assertEqual(json.loads(response.content), content) + self.assertEqual( + json.loads(response.content).get('non_field_errors'), + content.get('non_field_errors')) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) @@ -2082,7 +2086,9 @@ def test_create_with_invalid_single_use_token_no_profile(self): ] } - self.assertEqual(json.loads(response.content), content) + self.assertEqual( + json.loads(response.content).get('non_field_errors'), + content.get('non_field_errors')) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) @@ -2146,7 +2152,9 @@ def test_create_payment_issue(self): ] } - self.assertEqual(json.loads(response.content), content) + self.assertEqual( + json.loads(response.content).get('non_field_errors'), + content.get('non_field_errors')) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) diff --git a/store/views.py b/store/views.py index 192e2fa8..a3df2e0d 100644 --- a/store/views.py +++ b/store/views.py @@ -227,7 +227,10 @@ def cards(self, request, *args, **kwargs): ) except PaymentAPIError as err: return Response( - {'message': str(err)}, + { + 'message': str(err), + 'detail': err.detail + }, status=status.HTTP_400_BAD_REQUEST, )