[英]Continue running code if one aspect of a try block fails, but still raise the exception
作為將 excel 文件處理為具有多個 Python 函數的不同格式的更大腳本的一部分,我有這個 function 來實際運行所有其他函數:
print = logging.info
class MyException(Exception):
pass
@catch_exception_and_send_email
def validation_and_processing(file_list):
'''
This function the file list and runs each file in the directory through the validation and processing functions.
args:
file_list : output file path
'''
exceptions = []
for file in files:
try:
if file.startswith('Nomura'):
check_filename_format(input_file = file)
nomura = nomura_validation(input_dir = input_dir, file = file)
nomura_df = nomura_processing(nomura)
write_output(path=output_dir, filename=file, dataframe=nomura_df)
shutil.move(input_dir+file, archive_dir+file)
print("Congratulations! {} dealer file processed successfully on {} at {}".format(file, date, time))
elif file.startswith('MSTN'):
check_filename_format(input_file = file)
morgan = morgan_validation(input_dir = input_dir, file = file)
morgan_df = morgan_processing(morgan)
write_output(path=output_dir, filename=file, dataframe=morgan_df)
shutil.move(input_dir+file, archive_dir+file)
print("Congratulations! {} dealer file processed successfully on {} at {}".format(file, date, time))
elif file.startswith('JPM'):
check_filename_format(input_file = file)
jpm, input_file = jpm_validation(input_dir = input_dir, file = file)
jpm = jpm_processing(jpm, input_file)
write_output(path=output_dir, filename=file, dataframe=jpm)
shutil.move(input_dir+file, archive_dir+file)
print("Congratulations! {} dealer file processed successfully on {} at {}".format(file, date, time))
elif file.startswith('BofA'):
check_filename_format(input_file = file)
bofa_not_ginnie, bofa_ginnie = bofa_validation(input_dir=input_dir, file=file)
bofa_final = bofa_processing(df1=bofa_not_ginnie, df2=bofa_ginnie, input_file=file)
write_output(path=output_dir, filename=file, dataframe=bofa_final)
shutil.move(input_dir+file, archive_dir+file)
print("Congratulations! {} dealer file processed successfully on {} at {}".format(file, date, time))
elif file.startswith('CITI'):
check_filename_format(input_file = file)
citi = citi_validation(input_dir=input_dir, file=file)
citi_final = citi_processing(df=citi, input_file=file)
write_output(path=output_dir, filename=file, dataframe=citi_final)
shutil.move(input_dir+file, archive_dir+file)
print("Congratulations! {} dealer file processed successfully on {} at {}".format(file, date, time))
except (OSError, IOError, MyException):
# This should cast a wide net since:
# In 3.3, IOError became an alias for OSError,
# and FileNotFoundError is a subclass of OSError
# also catches PermissionError
# Source: https://stackoverflow.com/questions/15032108/pythons-open-throws-different-errors-for-file-not-found-how-to-handle-b/15032444#15032444
# Logs the error appropriately.
logging.error("Error with file:" + file)
continue
except Exception as e:
# Reraise exception adding info about which file
pass
raise Exception("Error with file:", file) from e
return exceptions
這個想法是,如果文件的 function 之一失敗,它應該引發異常,但仍應確保嘗試運行所有其他文件。 當我運行一個文件格式不正確的測試用例時,它會引發該文件的錯誤並成功完成該文件之前目錄中出現的文件,但不是之后的文件。 如果發生錯誤,我如何修改我的代碼以完成引發的錯誤(如果一個文件不正確,我需要代碼最終失敗,因為發送了 email 異常並且日志文件更新了錯誤),但仍然運行其他文件是否正確。
這是我構建日志文件的代碼。 我使用catch_exception_and_send_email
作為裝飾器 function 用於腳本中的其他函數,以防它們引發異常。
now = datetime.now()
date = now.strftime("%m_%d_%Y")
time = now.strftime("%H_%M_%S")
log_filename = "log_" + date + "_" + time + ".txt"
#Initialize log file
logging.basicConfig(filename=log_filename, level=logging.DEBUG, format='%(asctime)s %(levelname)s %(name)s %(message)s', force = True)
logger=logging.getLogger(__name__)
logging.getLogger('PIL').setLevel(logging.WARNING)
'''
The below function is a decorator function that checks every function in the file at runtime for exceptions,
and updates the log file and sends an email with details of exception
'''
def catch_exception_and_send_email(func):
def exception_catcher(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
print(e)
send_error_email(exception=e, message="An exception {} occurred in {}".format(e, func.__name__))
logging.exception('Oh no! {} On {} at {} in: {} function.'.format(e, date, time, func.__name__), exc_info = False)
sys.exit(1)
return exception_catcher
您需要能夠只保留異常:
def validation_and_processing(file_list):
'''
This function the file list and runs each file in the directory through the validation and processing functions.
args:
file_list : output file path
'''
exceptions = []
for file in files:
try:
if file.startswith('Nomura'):
...
...
except Exception as e:
exceptions.append(e)
return exceptions
目標是:
代碼
import traceback
import logging
def validation_and_processing(file_list):
'''
This function the file list and runs each file in the directory through the validation and processing functions.
args:
file_list : output file path
'''
for file in files:
try:
if file.startswith('Nomura'):
...
...
except (OSError, IOError, CustomExceptionName):
# This should cast a wide net since:
# In 3.3, IOError became an alias for OSError,
# and FileNotFoundError is a subclass of OSError
# also catches PermissionError
# Source: https://stackoverflow.com/questions/15032108/pythons-open-throws-different-errors-for-file-not-found-how-to-handle-b/15032444#15032444
# CustomExceptionName class similar to: https://stackoverflow.com/questions/1319615/proper-way-to-declare-custom-exceptions-in-modern-python/53469898#53469898
# Logs the error appropriately.
logging.exception("Error with file:" + file)
continue # continue processing
except Exception as e:
# Reraise exception adding info about which file
raise Exception("Error with file:", file) from e
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.