You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何捕获subprocess.call执行子进程时抛出的异常?

问题根本原因

subprocess.call() 本身的设计是不会因为被调用的外部命令执行失败(返回非0退出码)就抛出异常,只有当Python层面无法启动目标命令(比如node不存在、权限不足)时才会触发异常。你遇到的场景是node成功启动,但JS代码运行出错后node返回了非0退出码,subprocess.call()只会把这个退出码作为返回值返回,不会触发异常,因此现有try-except捕获不到。你后续的Python报错是因为JS执行失败后outputs.txt内容不符合预期,后续JSON解析逻辑报错导致的。

解决方案

方案1:直接检查subprocess.call()的返回值

subprocess.call()的返回值等于外部命令的退出码,0代表执行成功,非0代表执行失败:

import subprocess
try:
    print("Running code " + str(sub.id))
    # 2>&1是shell语法,把标准错误合并到标准输出一起写入文件,方便后续排查错误
    return_code = subprocess.call("node codes.js > outputs.txt 2>&1", shell=True)
    if return_code != 0:
        print(f"Error running submission code id {sub.id}, exit code: {return_code}")
        # 此处添加你的错误处理逻辑,比如跳过后续的JSON解析步骤
except Exception as e:
    # 此处捕获Python层面启动命令失败的异常,比如node未安装、路径不存在
    print(f"Error running submission code id {str(sub.id)}: {str(e)}")

方案2:使用subprocess.check_call()自动抛出异常

如果你希望命令执行失败时直接触发异常走except逻辑,可以用check_call()替代call(),它会在命令返回非0退出码时抛出subprocess.CalledProcessError异常:

import subprocess
try:
    print("Running code " + str(sub.id))
    subprocess.check_call("node codes.js > outputs.txt 2>&1", shell=True)
except subprocess.CalledProcessError as e:
    # 捕获外部命令执行失败的异常
    print(f"Error running submission code id {sub.id}, exit code: {e.returncode}")
except Exception as e:
    # 捕获其他启动层面的异常
    print(f"Error running submission code id {str(sub.id)}: {str(e)}")

进阶方案:直接在Python中捕获输出和错误,无需落盘文件

如果不想把输出写入本地文件,可以用subprocess.run()直接捕获stdout和stderr,同时推荐用列表形式传参避免shell注入风险(尤其适合判题这类用户输入不可控的场景):

import subprocess
try:
    print("Running code " + str(sub.id))
    result = subprocess.run(
        ["node", "codes.js"],
        capture_output=True,
        text=True,
        check=True # 开启后和check_call逻辑一致,非0退出码自动抛异常
    )
    # 执行成功后再把标准输出写入文件
    with open("outputs.txt", "w", encoding="utf-8") as f:
        f.write(result.stdout)
except subprocess.CalledProcessError as e:
    print(f"Error running submission code id {sub.id}")
    print(f"JS执行错误详情:{e.stderr}")
except Exception as e:
    print(f"Error running submission code id {str(sub.id)}: {str(e)}")

内容的提问来源于stack exchange,提问作者kofhearts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 09:06:03