[Answer]-Django : Propagate exception from models to a view

1đź‘Ť

âś…

The easy way to solve this problem is to simply catch the exception, and then re-raise it again. This will not solve the bigger problem which has to do with how your application is put together.

You should avoid coupling tightly your payment logic with your models; tomorrow if you have to add another payment provider, you’ll have a lovely time on your hands extracting that logic out of your models.

You should keep your logic of payment outside your views. Your payment view should deal with the amount and the payment method; anything else should be handled separately, here is what I suggest (highly simplified):

  1. Create a wrapper around the Stripe API for your application. This will make it easier to swap out Stripe or add additional providers later on.

  2. This wrapper should accept three things:

    1. The amount to be paid
    2. The date and time of the transaction
    3. The method of payment (this could be defaulted to Stripe)

    Your wrapper will then initiate the payment using the provider’s API and return either a success or fail condition, along with any payload that comes from the provider (like a transaction reference, etc.)

  3. Your view will intercept the result of the transaction, and if its success – update your models; if its failed, again, update your models and redirect the user accordingly.

This way you have:

  1. Made a pluggable architecture for your payment logic.
  2. Removed non-model related logic outside of your models.
  3. Made your views be the “controller” of the payment flow.
👤Burhan Khalid

0đź‘Ť

For better coherence I would catch the StipeError in the model, and raise another proper exception in the model, which the plan_view(..) could catch. That way the view can keep being ignorant of whatever fancy business goes on inside the model.

class Plan(models.Model):
    def update():
       try:
           // get the customer data related to id "xyz"
       except StipeError as error_obj:
           raise UpdateException() # define the exception outside of the model

….

def plan_view(request):
   .....
   try: 
      plan.update()
   except UpdateException:
     //redirect with exception message
👤Ludwig

Leave a comment