[英]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.