如何修改Python调用代码使出错的外部脚本终止主程序?
问题:调用出错的外部脚本时,主程序未终止运行
问题背景
我们有一个Python 3面向对象程序,需要调用第三方提供的外部脚本。当前问题是:当被调用的脚本返回非零退出码(执行出错)时,主程序仍会继续运行,而非报错终止。由于无法控制第三方脚本的内容,必须在主程序中添加错误处理逻辑。
复现步骤
- 创建两个目录
MyApp和AnotherDir,文件结构如下:AnotherDir\scripts\brokenScript.py MyApp\app\main.py MyApp\app\second_level.py MyApp\app\third_level.py - 导航到两个目录的父目录
- 执行命令:
python MyApp\app\main.py
当前结果
About to run a broken script that should break on error. command is: python C:\path\to\AnotherDir\scripts\brokenScript.py shell Inside broken script. The script should break on the next line. ---------------------------------------------------------------------------- FAILED TO THROW ERROR. Done running the broken script, but it returned without breaking this calling program. This print command should never run if the script breaks. Instead, a graceful error message should terminate the program.
期望结果
当brokenScript.py返回非零退出码时,主程序应捕获该错误并终止运行,而非继续执行后续代码。
解决方案:修改以下代码实现错误捕获与终止
1. 修改third_level.py中的runShellCommand函数
当前subprocess.Popen启动进程后,未检查进程的退出状态码。需在读取完输出后,获取返回码并判断是否为非零,若为非零则抛出异常:
def runShellCommand(self, commandToRun): proc = subprocess.Popen(commandToRun, cwd=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) while True: line = proc.stdout.readline() if line: thetext = line.decode('utf-8').rstrip('\r|\n') decodedline = self.ansi_escape.sub('', thetext) logString = decodedline print("shell", logString) else: break # 新增:等待进程结束并检查退出码 proc.wait() exit_code = proc.returncode if exit_code != 0: raise subprocess.CalledProcessError(exit_code, commandToRun)
2. 修改third_level.py中的runScript函数
调用runShellCommand时捕获异常,输出错误信息后终止程序:
def runScript(self, relativePathToScript): userCallingDir = str(os.path.abspath("."))+'\\' userCallingDir = self.formatPathForOS(userCallingDir) fullyQualifiedPathToScript = userCallingDir+relativePathToScript fullyQualifiedPathToScript = self.formatPathForOS(fullyQualifiedPathToScript) if os.path.isfile(fullyQualifiedPathToScript): commandToRun = "python "+fullyQualifiedPathToScript print("command is: ",commandToRun) try: self.runShellCommand(commandToRun) except subprocess.CalledProcessError as e: print(f"shell ERROR: 脚本执行失败,退出码 {e.returncode}") sys.exit(1) else: logString = "ERROR: "+fullyQualifiedPathToScript+" is not a valid path. " print('shell', logString) sys.exit(1)
3. (可选)优化second_level.py的错误处理
如果需要在业务层添加额外提示,可修改offFoundation函数捕获终止信号:
def offFoundation(self): tl = third_level() print("About to run a broken script that should break on error.") callScript = "\\AnotherDir\\scripts\\brokenScript.py" try: tl.runScript(callScript) except SystemExit: print("程序因外部脚本执行失败而终止") raise # 以下代码仅在脚本执行成功时运行 print("----------------------------------------------------------------------------") print("脚本执行成功完成")
内容的提问来源于stack exchange,提问作者CodeMed
相关产品推荐
相关产品推荐

