第六章:条件执行、重试与错误策略
GeoPipeAgent 提供了强大的流程控制能力,包括条件执行(when)、自动重试(retry)和错误跳过(skip)。本章详细介绍这些机制的工作原理和最佳实践。
6.1 错误策略:on_error
on_error 字段控制步骤失败时的行为,可取三个值:fail(默认)、skip、retry。
6.1.1 on_error: fail(默认)
步骤失败时立即终止整个流水线,抛出 StepExecutionError。JSON 报告的 status 为 "error"。
- id: critical-step
use: vector.clip
params:
input: "$load-data"
clip: "$load-boundary"
on_error: fail # 裁剪失败则终止,不产生错误数据
适用场景:关键处理步骤,失败后继续执行会产生无意义的结果。
6.1.2 on_error: skip
步骤失败时跳过该步骤,步骤状态标记为 "skipped",输出设为空 StepResult(),流水线继续执行后续步骤。
- id: optional-simplify
use: vector.simplify
params:
input: "$load-data"
tolerance: 0.001
preserve_topology: true
on_error: skip # 简化失败时跳过,使用原始几何继续
注意:跳过步骤后,其输出为空
StepResult()。后续步骤若引用该步骤,需通过when条件判断,避免将空值传给下一个步骤。
适用场景:
- 可选的优化步骤(简化、平滑等)
- 某些数据可能不需要的处理步骤
- 非关键的输出步骤(如保存中间结果)
6.1.3 on_error: retry
步骤失败时自动重试,最多 3 次,每次重试前等待递增时间(0.5s、1s、1.5s)。若 3 次都失败,抛出 StepExecutionError。
- id: geocode-address
use: network.geocode
params:
address: "北京市海淀区清华大学"
on_error: retry # 网络请求超时时自动重试
重试日志示例:
WARNING: Step 'geocode-address' attempt 1/3 failed: Connection timeout — retrying...
WARNING: Step 'geocode-address' attempt 2/3 failed: Connection timeout — retrying...
INFO: Step 'geocode-address' (network.geocode) completed in 2.341s
适用场景:
- 网络请求步骤(地理编码、API 调用)
- 可能因资源争用而偶发失败的步骤
- 外部服务不稳定时的容错处理
6.2 条件执行:when
when 字段接受一个条件表达式字符串。当表达式求值为 True 时,步骤正常执行;为 False 时,步骤状态标记为 "skipped"。
6.2.1 基本语法
- id: fix-geometry
use: qc.geometry_validity
params:
input: "$load-data"
auto_fix: true
when: "$check-geometry.issues_count > 0"
6.2.2 支持的表达式
when 表达式通过 safe_eval.py 中的 AST 白名单安全求值,支持以下语法:
比较运算符:
when: "$step.issues_count > 0"
when: "$step.feature_count >= 100"
when: "$step.issues_count == 0"
when: "$step.crs != 'EPSG:4326'"
逻辑运算符:
when: "$check.issues_count > 0 and ${auto_fix} == true"
when: "$check.issues_count > 0 or ${force_fix} == true"
when: "not ${skip_qc}"
真值检查(步骤输出非空):
when: "${enable_analysis}" # 变量为 true 时执行
when: "${enable_analysis} == true" # 等价写法
6.2.3 引用变量和步骤属性
在 when 中同样支持 ${var} 和 $step.attr:
pipeline:
variables:
enable_qc: true
min_features: 10
steps:
- id: load-data
use: io.read_vector
params: { path: "data.shp" }
# 基于变量的条件
- id: check-geometry
use: qc.geometry_validity
params: { input: "$load-data" }
when: "${enable_qc} == true"
# 基于步骤 stats 的条件
- id: report-small-dataset
use: io.write_vector
params:
input: "$load-data"
path: "warnings/small_dataset.geojson"
when: "$load-data.feature_count < ${min_features}"
6.2.4 when 求值失败时的行为
若 when 表达式因解析错误或引用不存在的属性而无法求值,框架记录警告日志并将结果视为 False(步骤跳过):
WARNING: Cannot evaluate when='$check.nonexistent > 0' (resolved='None > 0'), treating as False
这种”安全失败”策略避免了因条件表达式错误而中断流水线。
6.3 错误报告结构
当步骤失败时,JSON 报告会包含详细的错误信息:
{
"error": "StepExecutionError",
"step_id": "buffer-roads",
"message": "CRS mismatch: input uses geographic CRS (EPSG:4326), but distance in meters requires a projected CRS.",
"suggestion": "Add a vector.reproject step before this step to convert to a projected CRS.",
"cause": "Operation `buffer` is not supported for geographic coordinates..."
}
框架内置了智能错误建议(_suggest_fix 函数),针对常见错误自动提供修复建议:
| 错误模式 | 自动建议 |
|---|---|
| CRS 不匹配 / 地理坐标缓冲 | 在此步骤前添加 vector.reproject 转换为投影坐标系 |
| CRS 为 None | 设置 CRS 或确保源文件有 CRS 元数据 |
| 文件未找到 | 检查输入文件路径 |
| 权限错误 | 检查输入/输出路径的文件权限 |
| 不支持的格式 | 检查文件格式,支持 GeoJSON、Shapefile、GPKG |
| 无效几何 | 在此步骤前添加 qc.geometry_validity 步骤 |
| 空几何 | 用 vector.query 过滤掉空几何要素 |
| 字段不存在 | 检查字段名是否正确,用 io.read_vector stats 查看可用字段 |
6.4 综合实战:QC 驱动的条件修复流水线
下面是一个综合运用 when、on_error: skip、on_error: retry 的完整示例:
pipeline:
name: "数据入库前质检与修复"
description: "对输入矢量数据进行质检,有问题则自动修复,最终校验并入库"
variables:
input_path: "data/buildings.shp"
output_path: "output/buildings_clean.geojson"
auto_fix: true
steps:
# 步骤1:读取数据
- id: load-data
use: io.read_vector
params:
path: "${input_path}"
# 步骤2:坐标系检查(失败时跳过,不中断流程)
- id: check-crs
use: qc.crs_check
params:
input: "$load-data"
expected_crs: "EPSG:4326"
on_error: skip
# 步骤3:几何有效性检查
- id: check-geometry
use: qc.geometry_validity
params:
input: "$load-data"
auto_fix: false
severity: "error"
# 步骤4:仅在有几何问题时执行修复
- id: fix-geometry
use: qc.geometry_validity
params:
input: "$load-data"
auto_fix: true
when: "$check-geometry.issues_count > 0"
on_error: skip # 修复失败时跳过,用原始数据继续
# 步骤5:拓扑检查(失败时跳过)
- id: check-topology
use: qc.topology
params:
input: "$load-data"
rules: ["no_overlaps", "no_gaps"]
on_error: skip
# 步骤6:属性完整性检查(失败时跳过)
- id: check-attrs
use: qc.attribute_completeness
params:
input: "$load-data"
required_fields: ["name", "height", "type"]
severity: "warning"
on_error: skip
# 步骤7:保存质检问题报告(仅有问题时)
- id: save-issue-report
use: io.write_vector
params:
input: "$check-geometry.issues_gdf"
path: "output/geometry_issues.geojson"
format: "GeoJSON"
when: "$check-geometry.issues_count > 0"
on_error: skip
# 步骤8:保存最终结果(优先使用修复后数据)
- id: save-result
use: io.write_vector
params:
input: "$fix-geometry" # fix-geometry 若被跳过则为空,改用 load-data
path: "${output_path}"
format: "GeoJSON"
# 步骤9:地理编码示例(网络失败时重试)
- id: geocode-center
use: network.geocode
params:
address: "北京市中心"
on_error: retry
outputs:
result: "$save-result"
geometry_issues: "$check-geometry.issues_count"
topology_issues: "$check-topology.issues_count"
attr_issues: "$check-attrs.issues_count"
6.5 when 与 on_error 的协同使用
when 和 on_error 是两个独立的机制,可以组合使用:
# 场景:可选的优化步骤,仅在开启优化选项时执行,执行失败时跳过
- id: optimize-topology
use: vector.dissolve
params:
input: "$load-data"
by: "type"
when: "${enable_optimize} == true" # 满足条件才尝试执行
on_error: skip # 执行失败时跳过
执行逻辑:
- 若
when为False→ 步骤状态skipped,不执行(也不会触发on_error) - 若
when为True→ 执行步骤:- 成功 → 状态
success - 失败 +
on_error: skip→ 状态skipped,继续 - 失败 +
on_error: retry→ 重试 3 次,仍失败则终止 - 失败 +
on_error: fail→ 终止流水线
- 成功 → 状态
6.6 步骤被跳过后的引用处理
当步骤被跳过(status: skipped)时,其输出为空 StepResult(),即 output=None、stats={}。后续引用该步骤时需注意:
steps:
- id: optional-fix
use: qc.geometry_validity
params: { input: "$load-data", auto_fix: true }
when: "${apply_fix} == true" # 可能被跳过
# 危险:如果 optional-fix 被跳过,$optional-fix 为 None
- id: buffer
use: vector.buffer
params:
input: "$optional-fix" # ⚠️ 若 optional-fix 被跳过,此处传入 None 会失败
distance: 100
推荐处理模式:使用两个步骤,分别对应修复后数据和原始数据:
# 使用修复后数据(若修复步骤被跳过则该分支也跳过)
- id: buffer-fixed
use: vector.buffer
params:
input: "$optional-fix"
distance: 100
when: "${apply_fix} == true"
# 使用原始数据(当不需要修复时)
- id: buffer-original
use: vector.buffer
params:
input: "$load-data"
distance: 100
when: "${apply_fix} != true"
6.7 本章小结
本章全面介绍了 GeoPipeAgent 的流程控制机制:
on_error: fail(默认):关键步骤失败时终止流水线on_error: skip:可选步骤失败时跳过,继续执行on_error: retry:网络/外部服务步骤失败时自动重试(最多 3 次)when条件:基于前置步骤输出或变量值,有选择地执行步骤- 错误建议:框架内置智能错误建议,帮助快速定位和修复问题
- 协同使用:
when和on_error组合使用,构建健壮的自适应流水线
下一章将深入介绍 IO 步骤的使用方法,覆盖矢量和栅格数据的读写。