Databricks中如何将子Notebook的异常传递至父Notebook?
在Databricks中传递子Notebook的异常到父Notebook
要实现父Notebook捕获并区分子Notebook及孙Notebook的执行失败,核心是让子/孙Notebook在失败时主动抛出带标识的异常——因为dbutils.notebook.run默认不会将子Notebook的内部异常自动传递给父级。以下是具体实现方案:
核心原理
dbutils.notebook.run执行子Notebook时,只有当子Notebook抛出未被捕获的异常,才会将异常信息向上传递给父Notebook。因此需要修改子、孙Notebook的异常处理逻辑,将失败信息以异常形式抛出,而非仅打印提示。
步骤1:修改孙Notebook(../02_wbs/step_exec)
确保孙Notebook在执行失败时抛出带明确标识的异常,同时保留原始异常栈便于调试:
# ../02_wbs/step_exec 代码 try: # 替换为你的实际业务逻辑 df = spark.read.csv("invalid_file_path.csv") # 模拟执行失败场景 except Exception as e: # 抛出带"02 failed"标识的异常 raise Exception("02 failed") from e
步骤2:修改子Notebook(../01_load/main_exec)
捕获孙Notebook的异常后直接向上传递;若子Notebook自身出现错误(如路径错误),则抛出带"01 failed"标识的异常:
# ../01_load/main_exec 代码 try: dbutils.notebook.run("../02_wbs/step_exec", 0) except Exception as e: # 若捕获到孙Notebook的"02 failed"异常,直接传递给父级 if "02 failed" in str(e): raise e # 子Notebook自身执行失败,抛出对应标识异常 raise Exception("01 failed") from e
步骤3:修改父Notebook
捕获子Notebook抛出的异常,根据异常标识输出对应提示:
# 父Notebook代码 try: dbutils.notebook.run("../01_load/main_exec", 0) except Exception as e: error_content = str(e) if "02 failed" in error_content: print("02 failed") elif "01 failed" in error_content: print("01 failed") else: # 处理未预期的异常 print(f"Unexpected error occurred: {error_content}")
进阶方案:使用自定义异常类
如果需要更严谨的错误区分,可定义自定义异常类,避免字符串匹配的潜在问题:
- 在所有相关Notebook顶部定义相同的自定义异常:
class Step2Failure(Exception): """标记孙Notebook执行失败的异常""" pass class Step1Failure(Exception): """标记子Notebook执行失败的异常""" pass
- 孙Notebook抛出
Step2Failure:
# ../02_wbs/step_exec try: # 业务逻辑代码 df = spark.read.csv("invalid_file_path.csv") except Exception as e: raise Step2Failure() from e
- 子Notebook捕获并传递异常:
# ../01_load/main_exec try: dbutils.notebook.run("../02_wbs/step_exec", 0) except Step2Failure as e: raise e except Exception as e: raise Step1Failure() from e
- 父Notebook捕获不同异常类型:
# 父Notebook class Step2Failure(Exception): pass class Step1Failure(Exception): pass try: dbutils.notebook.run("../01_load/main_exec", 0) except Step2Failure: print("02 failed") except Step1Failure: print("01 failed") except Exception as e: print(f"Unexpected error: {str(e)}")
关键注意点
- 必须确保子/孙Notebook的异常未被完全吞噬,要通过
raise主动抛出给父级。 - 使用
raise ... from e可以保留原始异常栈,帮助定位问题根源。 - 若子Notebook需要返回执行结果,可结合
dbutils.notebook.exit()返回状态码,但异常传递更适合处理失败场景。
内容的提问来源于stack exchange,提问作者nikeiar222
相关产品推荐
相关产品推荐

