1

I've been trying to add an error handling mechanism to my code section. However when it runs it says 'continue outside of loop' but looking at the code it should be inside the try loop. What's going wrong?

def download_media_item(self, entry):
    try:
        url, path = entry
        # Get the file extension example: ".jpg"
        ext = url[url.rfind('.'):]
        if not os.path.isfile(path + ext):
            r = requests.get(url, headers=headers, timeout=15)
            if r.status_code == 200:
                open(path + ext, 'wb').write(r.content)
                self.user_log.info('File {} downloaded from {}'.format(path, url))
                return True
            elif r.status_code == 443:
                print('------------the server reported a 443 error-----------')
                return False
        else:
            self.user_log.info('File {} already exists. URL: {}'.format(path, url))
            return False
    except requests.ConnectionError:
        print("Received ConnectionError. Retrying...")
        continue
    except requests.exceptions.ReadTimeout:
        print("Received ReadTimeout. Retrying...")
        continue   
9
  • You have no for loop. Commented Sep 15, 2020 at 12:51
  • Your continue statements are not inside any loop. Are you saying that there is a for loop somewhere? Commented Sep 15, 2020 at 12:51
  • What for loop? Both of the continue statements in your except cases are outside of a loop Commented Sep 15, 2020 at 12:52
  • You don't need continue to continue execution following the try statement; that already happens. For example, omitting continue from except requests.ConnectionError does not cause the except requests.exceptions.ReadTimeout block to execute next. Commented Sep 15, 2020 at 12:53
  • 1
    Do or do not, there is no try loop. Commented Sep 15, 2020 at 12:58

2 Answers 2

3

It seems that what you are actually wanting to do is keep looping until no exception is raised.

In general, you can do this by having an infinite loop that you break from in the event of a successful completion.

Either:

while True:
    try:
        # do stuff
    except requests.ConnectionError:
        # handle error
        continue
    except requests.exceptions.ReadTimeout:
        # handle error
        continue
    break

Or:

while True:
    try:
        # do stuff
    except requests.ConnectionError:
        # handle error
    except requests.exceptions.ReadTimeout:
        # handle error
    else:
        break

However, in this case, the "do stuff" seems to always end by reaching a return statement, so the break is not required, and the following reduced version would suffice:

while True:
    try:
        # do stuff
        return some_value
    except requests.ConnectionError:
        # handle error
    except requests.exceptions.ReadTimeout:
        # handle error

(The single return shown here may refer to alternative control flows, all of which lead to a return, as in your case.)

Sign up to request clarification or add additional context in comments.

3 Comments

I don't think the OP needs any break specifically since their current code always seems to have a return path if there is no exception. Anyway, its a +1 from me.
@quamrana Good point, thank you. I didn't look closely enough at the details of the "do stuff" in this case. I'll add your observation as a note at the end, but in terms of possible more generic use I think I'll leave the answer otherwise as-is.
@quamrana Now updated to reflect this. Thanks again for the observation.
2

continue is specifically for immediately moving to the next iteration of a for or while loop; it is not an all-purpose move-to-the-next-statement instruction.

In a try/except statement, anytime you reach the end of a try, except, else, or finally block, execution proceeds with the next complete statement, not the next portion of the try statement.

def download_media_item(self, entry):
    # 1: try statement
    try:
        ...
        # If you get here, execution goes to #2 below, not the
        # except block below
    except requests.ConnectionError:
        print("Received ConnectionError. Retrying...")
        # Execution goes to #2 below, not the except block below
    except requests.exceptions.ReadTimeout:
        print("Received ReadTimeout. Retrying...")
        # Execution goes to #2 below

    # 2: next statement
    ...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.