How do I make Django continue executing code after throwing an exception?

Hi there,

I am working on a Django app where I need to check exceptions a lot and then throw them in models.py and views.py. My question is, let’s say I am in a view, and I need to catch and throw an exception in the middle of that view. How do I make Django keep executing the rest of the view even after throwing the exception?

For example, I have the following views.py (only some methods and relevant details are shown):

class PasswordResetRequest(View):
    def get(self, request):
        password_reset_request_form = PasswordResetForm()

        context = {
            "title": "Reset Your Password",
            "password_reset_request_form":
                password_reset_request_form,
        }

        return render(request, "accounts/password-reset.html", context)

    def post(self, request):
        password_reset_request_form = PasswordResetForm(request.POST)

        context = {
            "title": "Reset Your Password",
            "password_reset_request_form": password_reset_request_form,
        }

        if password_reset_request_form.is_valid():
            try:
                user = User.objects.get(
                    email=password_reset_request_form\
                        .cleaned_data["email"]
                )
            except Exception as ex:
                raise Exception("ERROR: Could not get User \
                    instance because email enetred does not \
                    exist in the database")  # AFTER THIS EXCEPTION IS RAISED, I WANT DJANGO TO EXECUTE THE REST OF THE VIEW. HOW CAN I MAKE IT POSSIBLE?
            else:
                user = None

            if user is None:
                result = self.post_decision(user, request, context)

                return result["return"]

            status_message = user.send_password_reset_email()

            result = self.post_decision(
                user,
                request,
                context,
                status_message
            )

            return result["return"]
        else:
            messages.error(
                request,
                f"ERROR: You did not fill all the fields of form."
            )

            return render(
                request,
                "accounts/password-reset.html",
                context
            )

Any help will be appreciated.

Simple answer is that you don’t.

A raised exception is a transfer of control of execution.

You can catch exceptions at any level, but you do not have the ability to return control to the point where the exception is raised.

In that case, how do I handle the exceptions that they don’t get swallowed and I keep continuing executing the code after exception is catched?

You don’t - things don’t work that way.

You need to handle what you want handled in your catch and allow things to proceed from there. What you’re wanting to do appears to be to call some other component. You need to create some method to call that component. You don’t use an exception to send a message or signal.

1 Like

I think one question that also makes sense is: why are you raising a exception?
It seems that you can handle the case of not having a user found for some email.

Normally you raise a exception when you CAN’T handle a certain state.

I’d qualify that statement. The real situation is a bit more nuanced than that.

It’s not that you “can’t” handle a state.

You would typically raise an exception when you don’t want to handle the exception at that location.

Or to phrase it a different way - you raise the exception when you want to abandon the current function - situations where you don’t want the rest of the current function to complete.

(Think of all the “normal” exceptions that are thrown in the routine sequence of events.)

Unlike many (most?) other languages, Python considers Exceptions to be normal.

You’re right!
In this case i really think that the .get call here should be replaced by a first.

I don’t see where that helps anything. He’s still left in the position where he needs to check if an item is found.

The problem here isn’t the use of the try / except for the get, it’s using the raise to try and do something else other than abandoning the current function.