I am trying to add error handling to this program by adding try and except blocks in case something does not work and so that the program does not shutdown in case there is an error in handling the data. (This is a dumbed down version of my code). When I run it this way, (given that the time is accurate), nothing seems to work - the functions in report_scheduler do not actually ever run.
Here is the code I am looking at:
import schedule
def forex_data_report():
from forex_python.converter import CurrencyRates
import csv
current_dir = os.getcwd()
date_time = time.strftime('%m-%d-%Y_at_%I-%M-%S-%p')
c = CurrencyRates()
usd_eur = c.get_rate('EUR', 'USD')
usd_gbp = c.get_rate('GBP', 'USD')
usd_yen = c.get_rate('JPY', 'USD')
usd_aud = c.get_rate('AUD', 'USD')
eur_gbp = c.get_rate('GBP', 'EUR')
clean_file_location = current_dir + '\\Reports\\Forex_Data\\Forex_Data.csv'
with open(clean_file_location, 'a', newline='') as outfile:
writer = csv.writer(outfile)
writer.writerow([date_time, usd_eur, usd_gbp, usd_yen, usd_aud, eur_gbp])
send_outlook_w_attach('Key Currencies', clean_file_location)
print ('Updated Key Currencies Data.')
def competitor_stock_data_report():
import datetime
import pandas_datareader.data as web
import csv
current_dir = os.getcwd()
date_print = time.strftime('%m-%d-%Y_at_%I-%M-%S-%p')
date_time = datetime.datetime.now()
date = date_time.date()
stocklist = ['LAZ','AMG','BEN','LM','EVR','GHL','HLI','MC','PJT','MS','GS','JPM','AB']
start = datetime.datetime(date.year-1, date.month, date.day-1)
end = datetime.datetime(date.year, date.month, date.day-1)
clean_file_location = current_dir + '\\Reports\\XXX\\Stock_Data.csv'
for x in stocklist:
df = web.DataReader(x, 'google', start, end)
with open(clean_file_location, 'a', newline='') as outfile:
writer = csv.writer(outfile)
writer.writerow([date_print, x, df.loc[df.index[0], 'Close'], df.loc[df.index[-1], 'Close']])
send_outlook_w_attach('Competitor Stock Data vs. XXX', clean_file_location)
print ('Updated XXX Competitor Stock Performance Data.')
def report_scheduler():
try:
schedule.every().day.at("00:00").do(forex_data_report)
except:
pass
try:
schedule.every().friday.at("00:01").do(competitor_stock_data_report)
except:
pass
while True:
schedule.run_pending()
time.sleep(1)
if __name__ == '__main__':
print('Starting background - HANDLER - process...')
report_scheduler()
I understand the pass is not error handling, but I do need some sort of way to tell the program to continue, even if the data is not being updated/an error occurs.
Thanks.
2 Answers 2
Without actually getting deep into your code, probably an exception is being raised and then caught and then the pass statement means you don't get any output.
Have you checked it runs without the try except blocks?
Also, this might help:
except Exception as e:
print("Exception raised: {}".format(e))
At least then you will get a printout of your exception. You might also want to look into logging the exception.
2 Comments
I'm not familiar with the libraries you are using - it would be very helpful if you would post a complete program that we could tinker with ourselves, and name all of the third-party libraries involved - but I suspect you want the try-except blocks inside forex_data_report and competitor_stock_data_report. You aren't concerned with exceptions thrown by the act of scheduling the periodic task, are you? You want to swallow exceptions from the periodic tasks themselves. Experiment with code structured like this:
def forex_data_report():
# unchanged
def forex_data_report_wrapper():
try:
forex_data_report()
except Exception as e:
logger.exception(e)
# similarly for competitor_stock_data_report
def report_scheduler():
schedule.every().day.at("00:00").do(forex_data_report_wrapper)
schedule.every().friday.at("00:01").do(competitor_stock_data_report_wrapper)
while True:
schedule.run_pending()
time.sleep(1)
Note also that I am using except Exception instead of except. A bare except catches things you almost certainly don't want to catch, such as KeyboardInterrupt and StopIteration.
report_schedulerschedule?