What is the correct way to save a caught exception and use it outside the function for system exit handling purposes?

Question:

*** Modified based on suggestions. But where i’m struggling is to find the right way to check if an exception occurred and append to the saved exception list. As the function has return value, None check doesn’t work. Any suggestions with the modified code? ****

I’m building a python application. The Application has two functions – Make a series of API calls based on parameter and write the response to a file. It works fine when it encounters a handled exceptions and continues executing the rest of the code.

But what I really want is to save the exception details to a variable, continue with the execution and at the end of the program, check if any exception was caught, print it and exit with 1. An external monitoring app will do some post processing with this data.

I have tried it, but it’s not working as intended. Any suggestions on how to make it work?

import traceback, sys
import requests
import sys
import logging
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry

# logging.basicConfig(level=logging.DEBUG)

save_exc_info = []  # declare a variable to save an exception


def api_test(endpoint):
    try:
        print('Starting the API trigger')
        headers = {'Connection': 'keep-alive'}
        session = requests.Session()
        retries = Retry(total=2, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504],
                        method_whitelist=["GET", "POST"])
        session.mount('https://', HTTPAdapter(max_retries=retries))
        response = session.get(endpoint, timeout=3, headers=headers)
        response.raise_for_status()
        print('Job completed successfully')
        return response # return value from function

    except requests.exceptions.HTTPError as e:
        print('HTTP error occurred while making the  API' + str(traceback.format_exc()))
        return e # return exception as e


    except requests.exceptions.ConnectionError as e:
        print('Connection error occurred while making the API call' + str(traceback.format_exc()))
        return e # return exception as e


def write_response_to_file(file, endpoint):
    data_from_api = api_test(endpoint) # second function calls the first to get the API response

    try:
        if data_from_api.text:
            with open(file, 'a') as file_to_write:
                file_to_write.write(data_from_api.text)
                print('Successful write to local')
        else:
            with open(file, 'w'):
                print('write empty file')

    except (IOError, OSError) as e:
        print('Failure occurred while writing the API data')
        return e # return exception as e


file_location = 'C:\localpath\test.json'

api_trigger = [1, 2, 3]

for triggers in api_trigger:
    service = 'https://postman-echo.com/delay/' + str(triggers)
    excep = write_response_to_file(file_location, service)
    if excep: # What is the correct way to check for exception and append to saved exception list
        save_exc_info.append(excep)

if save_exc_info:  # Check if exception occurred
    print('Failure occurred during execution')  # print msg and the actual exception
    print(save_exc_info)
    sys.exit(1)  # Final system exit code 1 if any exception occurred
Asked By: RmDmachine

||

Answers:

You need to save the return object… try something like this:

def write_response_to_file(file, endpoint):

    data_from_api = api_test(endpoint)

    if data_from_api.text:
        with open(file, 'a') as file_to_write:
            file_to_write.write(data_from_api.text)
            print('Successful write to local')
    else:
        with open(file, 'w'):
            print('write empty file')


file_location = 'C:\localpath\test.json'

api_trigger = [1, 2, 3]

exceptions = []

for triggers in api_trigger:
    service = 'https://postman-echo.com/delay/' + str(triggers)
    try:
        write_response_to_file(file_location, service)
    except (IOError, OSError) as e:
        print('Failure occurred while writing the API data')
        exceptions.append(e)

if exceptions:  # Check if exception occurred
    print('Failure occurred during execution')  # print msg and the actual exception
    for e in exceptions:
        print(e)
    sys.exit(1)  # Final system exit code 1 if any exception occurred
Answered By: Amir

Try this out:

#This function will fail and return and exception.
def doSomething():
 try:
  #More stuff.
  pass
 except Exception as localE:
  #If the exception occurs inside a function you'll need to return it in order of appending in to 'exceptions' in the main code...
  return localE 



#Create a list of exceptions...
exceptions=[]
try:
 #Stuff.
 pass
except Exception as e:
 #If the exception occurs on the main globa code you can just append it to the list...
 exceptions.append(e)

#Execute a function...
excep=doSomething()
#If the function doesn't return None it means that an exception occured, so you should append the returned value.
if excep!=None:
 exceptions.append(excep)

#We check if there were any exceptions, if there were exceptions we print them...
if exceptions==[]:
 print("No execptions occured.")
else:
 print("[ERROR] The following exceptions took place during the execution of the program:")
 for i in range(len(exceptions)):
  print(f"{i}: {exceptions[i]}") 

The example should work with execeptions taking place in the main code and within functions, however, if you want to get some output from the functions apart of the exceptions you should change the code so that instead of checking if the value returned is none it checks if the value returned is an exceptions or the value that you were expecting.
I hope it helps.

-Update:
If you want to check if excep is an exception in your code you should do this:

excep=write_response_to_file(args)
if excep!=None:
 #There was an exception.
 exceptionList.append(excep)

You can use the same method from my original example as write_response_to_file() doesn’t return anything when there aren’t any exceptions.

Answered By: Asriel

I will suggest use

try:
    ...
except Exception as e:
    ...
else:
    ...

if try block raise an exception it will be caught by except block and if try block don’t rias anyexception then else block will execute.

Answered By: Nitesh
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.