0

I have a nested loop to get certain JSON elements the way I want, but occasionally, the API I'm fetching from gets messy and it breaks some of the fields - I am not exactly sure how to handle this since It seems to be different each time, so I'm wondering if there is a way to continue a nested for loop even if an exception occurs inside it, or at least go back to the first loop and continue again.

My code is like this:

 fields = ['email', 'displayname', 'login']
    sub_fields = ['level', 'name']

    all_data = []
    for d in data:
        login_value = d['login']
        if login_value.startswith('3b3'):
            continue
        student = fetched_student.student_data(login_value)
        student = json.loads(student)
        final_json = dict()
        try:
            for field in fields:
                #print ("Student field here: %s" % student[field])
                final_json[field] = student[field]
        except Exception as e:
            print (e) # this is where I get a random KeyValue Error
            #print ("Something happening here: %s " % final_json[field])
        finally:
            for sub_field in sub_fields:
                for element in student['users']:
                    if element.get(sub_field):
                        final_json[sub_field] = element.get(sub_field)
                for element in student['campus']:
                    if element.get(sub_field):
                        final_json[sub_field] = element.get(sub_field)
        all_data.append(final_json)
        print (all_data)

Is there a way to just go back to the first try block and continue after the exception has occurred or simply just ignore it and continue? Because as things are now, if the exception ever occurs it breaks everything.

EDIT1: I have tried putting continue like so:

try:
    for field in fields:
        #print ("Student field here: %s" % student[field])
        final_json[field] = student[field]
except Exception as e:
    print (e)
    continue
    for sub_field in sub_fields:
        for element in student['users']:

But it still fails regardless.

6
  • continue is the statement you are looking for. Commented Feb 19, 2020 at 19:54
  • 1
    Can you edit your question to show some examples of the data that you get when you succeed vs when you fail? Commented Feb 19, 2020 at 19:54
  • @jordanm I have tried putting continue instead of the finally block, but it still crashes the same way. Commented Feb 19, 2020 at 19:55
  • @GreenCloakGuy Sure, one moment. Commented Feb 19, 2020 at 19:58
  • Lower the try block to after the for statement so you start the loop and catch the exceptions inside of the loop. That way the continue statement will affect that specific loop and not the outer loop Commented Feb 19, 2020 at 20:05

2 Answers 2

1

Use this for the try block:

for field in fields:
   try:
       #print ("Student field here: %s" % student[field])
       final_json[field] = student[field]
    except Exception as e:
        print (e)
        continue
for sub_field in sub_fields:
    for element in student['users']:

The issue is due to the indentation level of the try block, the continue was affecting the outer most loop. Changing the try block to be inside of the loop will catch the error in that loop and continue the iteration of that specific loop.

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

6 Comments

I will try it as soon as my VPN connection comes back, thanks for the reply!
The problem is that the code could get stuck in an infinite loop. And rather than catch any exception, I would catch only the exceptions that are relevant to that particular operation. So just do: except KeyError: (or whatever exception you get) instead of: except Exception as e:. Also, if the API is misbehaving for reasons beyond your control and you detect that the data is corrupted (the exception occurs), then I would restart all over rather than continue with the loop ignoring errors. You risk ending up with inaccurate data.
Please elaborate since continue goes to the next iteration how would it get stuck in an infinite loop? This is following the format OP wants it in, and I disagree we could get into an infinite loop since it will go to the last value in fields. And everything else you are saying can be considered but is outside of the scope of this particular question.
If it was a while loop I can see how we could get into an infinite loop.But since the for loop has an upper bound which is the condition to end I fail to see how that would happen in this case
@EdekiOkoh So I tried this but it still didn't work, this is the exception I get for element in student['users']: KeyError: 'users'
|
0

Possibly you can use dict's get method like this in your try block:

try:
    for field in fields:
        #print ("Student field here: %s" % student[field])
        final_json[field] = student.get(field, "") # 2nd arg is fallback object

Depending on what is needed, you can pass in an fresh dict (aka JSON object), fresh list (aka JSON array), or a str like above to suit your downstream needs.

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.