Search code examples
pythonkeyerrortry-except

Do you have to use multipe try excepts for various KeyErrors closely coupled? Can they be combined without losing functionality in Try clause


Let's imagine I'm trying to print results from a request response. If I have multiple parameters I want to check, but may not necessarily be in every response I can contain them in a try clause that will check for a KeyError.

Problem is, I still would like to print the results. In my example below, if X-Next-Token is not a key in my results, I won't be able to print parameters pulled below.

Is there a design pattern for this that wouldn't require having to break out individual try and except clauses for every printing parameter example.

def print_response(response):
    
    print(response)
    results = response.json()['results']
    try:
        print(response.elapsed.total_seconds())
        print(response.headers["X-Next-Token"])
        print("First updatedAt:", results[0]['updatedAt'])
        print("Last updatedAt:", results[-1]['updatedAt'])
    except KeyError as e:
        print("There is no key:", e)

Solution

  • There is a few way to do this:

    Separate try - expect

    def print_response(response):
        
        print(response)
        results = response.json()['results']
        try:
            print(response.elapsed.total_seconds())
        KeyError as e:
            print("There is no key:", e)
        try:
            print(response.headers["X-Next-Token"])
        KeyError as e:
            print("There is no key:", e)
        try:
            print("First updatedAt:", results[0]['updatedAt'])
        KeyError as e:
            print("There is no key:", e)
        try:    
            print("Last updatedAt:", results[-1]['updatedAt'])
        KeyError as e:
            print("There is no key:", e)
    
    

    Or as @Nick Bailey suggested, use get

    def print_response(response):
        
        print(response)
        results = response.json()['results']
        print(response.elapsed.total_seconds())
        print(response.headers.get("X-Next-Token",""))
        print("First updatedAt:", results[0].get('updatedAt',"Not available"))
        print("Last updatedAt:", results[-1].get('updatedAt',"Not available"))
        
    

    or you can check if value exist, this does the same as using get method in dict

    def print_response(response):
        
        print(response)
        results = response.json()['results']
        print(response.elapsed.total_seconds())
        print("X-Next-Token" in response.headers and response.headers["X-Next-Token"] or "")
        print("First updatedAt:", "updatedAt" in results[0] and resutls[0]["updatedAt"] or "Not available")
        print("Last updatedAt:", "updatedAt" in results[-1] and results[-1]["updatedAt"] or "Not available")