feat: 增强 HTTP checker 鲁棒性 — 严格配置校验、完整耗时、流式body、重定向与编码完善
启动期校验: 新增 validate.ts 对 HTTP config/expect/body rule/operator 全方位严格校验 执行语义: body 改为 Web Stream 流式超限中止,durationMs 覆盖完整执行 错误归属: status/header 失败不读 body,phase 分层 request/body,early duration skip body 重定向: 跟随前释放 body,POST/303 改 GET 清理 header,跨 origin 剥离敏感 header 编码: 支持 quoted charset,未知编码返回结构化解码错误 文档: README match→regex+durationMs,DEVELOPMENT 执行流程与错误归属 测试: +63 测试覆盖全部新增场景,325 pass 0 fail 规格: 同步 probe-config/probe-engine/expect-body-checkers 3 个 delta spec
This commit is contained in:
@@ -128,7 +128,11 @@
|
||||
- **THEN** 系统 MUST 截断 actual 摘要,而不是持久化完整响应体或命令输出
|
||||
|
||||
### Requirement: 状态码范围匹配
|
||||
系统 SHALL 支持在 `expect.status` 数组中使用范围模式字符串(如 `"2xx"`、`"3xx"`、`"4xx"`、`"5xx"`),与精确数字混合使用。范围模式 SHALL 匹配对应百位段内的所有状态码。
|
||||
系统 SHALL 支持在 `expect.status` 数组中使用范围模式字符串(`"1xx"`、`"2xx"`、`"3xx"`、`"4xx"`、`"5xx"`),与精确数字混合使用。范围模式 SHALL 匹配对应百位段内的所有状态码。其他范围模式 SHALL 在启动期配置校验失败。
|
||||
|
||||
#### Scenario: 1xx 范围匹配
|
||||
- **WHEN** HTTP target 配置 `expect.status: ["1xx"]`,且响应状态码为 101
|
||||
- **THEN** 系统 SHALL 判定状态码匹配
|
||||
|
||||
#### Scenario: 2xx 范围匹配
|
||||
- **WHEN** HTTP target 配置 `expect.status: ["2xx"]`,且响应状态码为 200
|
||||
@@ -153,3 +157,57 @@
|
||||
#### Scenario: 5xx 范围匹配
|
||||
- **WHEN** HTTP target 配置 `expect.status: ["5xx"]`,且响应状态码为 503
|
||||
- **THEN** 系统 SHALL 判定状态码匹配
|
||||
|
||||
#### Scenario: 非 HTTP 范围模式启动失败
|
||||
- **WHEN** HTTP target 配置 `expect.status: ["6xx"]`
|
||||
- **THEN** 系统 SHALL 在启动期配置校验失败
|
||||
|
||||
### Requirement: HTTP expect 规则启动期校验
|
||||
系统 SHALL 在启动期校验 HTTP expect 中已支持字段的类型、格式和可编译表达式。未知字段 SHALL 被忽略,但每个规则对象 MUST 至少包含可产生有效断言的支持字段。
|
||||
|
||||
#### Scenario: body rule 使用 regex 字段
|
||||
- **WHEN** HTTP target 配置 `expect.body: [{regex: "ok|healthy"}]` 且 regex 可编译
|
||||
- **THEN** 系统 SHALL 接受该配置,并在运行期按 regex body 规则匹配响应体
|
||||
|
||||
#### Scenario: body rule 不支持 match 字段
|
||||
- **WHEN** HTTP target 配置 `expect.body: [{match: "ok"}]` 且该规则没有 contains、regex、json、css、xpath 任一支持字段
|
||||
- **THEN** 系统 SHALL 在启动期配置校验失败
|
||||
|
||||
#### Scenario: body rule 忽略未知字段
|
||||
- **WHEN** HTTP target 配置 `expect.body: [{contains: "ok", note: "ignored"}]`
|
||||
- **THEN** 系统 SHALL 忽略 note 字段并按 contains 规则校验响应体
|
||||
|
||||
#### Scenario: body rule 多支持字段非法
|
||||
- **WHEN** HTTP target 的同一条 body rule 同时配置 contains 和 regex
|
||||
- **THEN** 系统 SHALL 在启动期配置校验失败
|
||||
|
||||
#### Scenario: operator match 正则非法
|
||||
- **WHEN** HTTP target 的 expect.headers、json、css 或 xpath operator 配置了不可编译的 match 正则
|
||||
- **THEN** 系统 SHALL 在启动期配置校验失败
|
||||
|
||||
#### Scenario: operator 数值比较类型非法
|
||||
- **WHEN** HTTP target 的 expect operator 配置 gt、gte、lt 或 lte,且对应值不是有限数字
|
||||
- **THEN** 系统 SHALL 在启动期配置校验失败
|
||||
|
||||
#### Scenario: operator 布尔类型非法
|
||||
- **WHEN** HTTP target 的 expect operator 配置 empty 或 exists,且对应值不是布尔值
|
||||
- **THEN** 系统 SHALL 在启动期配置校验失败
|
||||
|
||||
#### Scenario: JSONPath 子集非法
|
||||
- **WHEN** HTTP target 的 json body rule path 不符合系统支持的 JSONPath 子集
|
||||
- **THEN** 系统 SHALL 在启动期配置校验失败
|
||||
|
||||
### Requirement: HTTP body 运行期失败结构化
|
||||
系统 SHALL 将 HTTP body 运行期失败记录为结构化 CheckFailure,并保留与具体规则相关的 phase 和 path。响应内容不符合配置 SHALL 记录为 mismatch;响应内容无法按配置解析或解码 SHALL 记录为 error。
|
||||
|
||||
#### Scenario: JSON 响应不是合法 JSON
|
||||
- **WHEN** HTTP target 配置 json body rule,但响应体不是合法 JSON
|
||||
- **THEN** 系统 SHALL 记录 `failure.kind="error"`、`failure.phase="body"`,且 failure.path SHALL 指向对应 json 规则
|
||||
|
||||
#### Scenario: CSS selector 无匹配元素
|
||||
- **WHEN** HTTP target 配置 css body rule,但响应 HTML 中无匹配元素
|
||||
- **THEN** 系统 SHALL 记录 `failure.kind="mismatch"`、`failure.phase="body"`,且 failure.path SHALL 指向对应 css 规则
|
||||
|
||||
#### Scenario: XPath 无匹配节点
|
||||
- **WHEN** HTTP target 配置 xpath body rule,但响应 XML/HTML 中无匹配节点
|
||||
- **THEN** 系统 SHALL 记录 `failure.kind="mismatch"`、`failure.phase="body"`,且 failure.path SHALL 指向对应 xpath 规则
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
- **THEN** 系统 SHALL 以错误退出并提示文件不存在
|
||||
|
||||
### Requirement: 配置校验
|
||||
系统 SHALL 在启动时对 YAML 配置进行完整校验,校验失败时以非零状态退出并输出清晰的错误信息。
|
||||
系统 SHALL 在启动时对 YAML 配置进行完整校验,校验失败时以非零状态退出并输出清晰的错误信息。HTTP checker SHALL 对已支持字段执行严格启动期校验;未知字段 SHALL 被忽略,不触发启动失败且不影响运行行为。
|
||||
|
||||
#### Scenario: target 缺少必填字段
|
||||
- **WHEN** YAML 中某个 target 缺少 name 或 type 字段
|
||||
@@ -105,10 +105,70 @@
|
||||
- **WHEN** YAML 中某个 HTTP target 的 `http.ignoreSSL` 不是布尔值
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 target 的 ignoreSSL 必须为布尔值
|
||||
|
||||
#### Scenario: HTTP headers 类型非法
|
||||
- **WHEN** YAML 中某个 HTTP target 的 `http.headers` 不是对象,或任一 header 名和值不能作为字符串使用
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 target 的 http.headers 格式错误
|
||||
|
||||
#### Scenario: HTTP body 类型非法
|
||||
- **WHEN** YAML 中某个 HTTP target 的 `http.body` 已配置但不是字符串
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 target 的 http.body 必须为字符串
|
||||
|
||||
#### Scenario: maxBodyBytes 数字非法
|
||||
- **WHEN** YAML 中某个 HTTP target 的 `http.maxBodyBytes` 或 defaults.http.maxBodyBytes 是负数、非整数或非安全整数
|
||||
- **THEN** 系统 SHALL 以错误退出,提示 maxBodyBytes 必须为非负安全整数字节数或合法 size 字符串
|
||||
|
||||
#### Scenario: status 模式非法
|
||||
- **WHEN** YAML 中某个 HTTP target 的 `expect.status` 包含不符合 `数字xx` 格式的字符串(如 `"abc"`、`"2x"`)
|
||||
- **WHEN** YAML 中某个 HTTP target 的 `expect.status` 包含不符合 `1xx` 到 `5xx` 格式的字符串(如 `"abc"`、`"2x"`、`"6xx"`)
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 target 的 status 模式不合法
|
||||
|
||||
#### Scenario: status 数字非法
|
||||
- **WHEN** YAML 中某个 HTTP target 的 `expect.status` 包含非整数或不在 100-599 范围内的数字
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 target 的 status 数字不合法
|
||||
|
||||
#### Scenario: maxDurationMs 非法
|
||||
- **WHEN** YAML 中某个 target 的 `expect.maxDurationMs` 不是非负有限数字
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 target 的 expect.maxDurationMs 格式错误
|
||||
|
||||
#### Scenario: HTTP expect headers 非法
|
||||
- **WHEN** YAML 中某个 HTTP target 的 `expect.headers` 不是对象,或某个 header 期望既不是字符串也不是合法 operator
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 target 的 expect.headers 格式错误
|
||||
|
||||
#### Scenario: HTTP expect body 必须为数组
|
||||
- **WHEN** YAML 中某个 HTTP target 的 `expect.body` 已配置但不是数组
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 target 的 expect.body 必须为数组
|
||||
|
||||
#### Scenario: HTTP body rule 缺少支持字段
|
||||
- **WHEN** YAML 中某个 HTTP target 的 `expect.body` 数组项未包含 contains、regex、json、css、xpath 任一支持字段
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 body rule 缺少支持的规则类型
|
||||
|
||||
#### Scenario: HTTP body rule 同时配置多个支持字段
|
||||
- **WHEN** YAML 中某个 HTTP target 的同一条 body rule 同时包含 contains、regex、json、css、xpath 中的多个支持字段
|
||||
- **THEN** 系统 SHALL 以错误退出,提示每条 body rule 只能配置一种规则类型
|
||||
|
||||
#### Scenario: HTTP body regex 非法
|
||||
- **WHEN** YAML 中某个 HTTP target 的 body regex 规则不是字符串或不是可编译正则表达式
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 body regex 不合法
|
||||
|
||||
#### Scenario: HTTP body json path 非法
|
||||
- **WHEN** YAML 中某个 HTTP target 的 body json 规则缺少 path,或 path 不符合系统支持的 JSONPath 子集
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 body json path 不合法
|
||||
|
||||
#### Scenario: HTTP body css selector 非法
|
||||
- **WHEN** YAML 中某个 HTTP target 的 body css 规则缺少 selector,或 selector 不是非空字符串
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 body css selector 不合法
|
||||
|
||||
#### Scenario: HTTP body xpath path 非法
|
||||
- **WHEN** YAML 中某个 HTTP target 的 body xpath 规则缺少 path,或 path 不是非空字符串,或可被现有 XPath 库静态判定为语法错误
|
||||
- **THEN** 系统 SHALL 以错误退出,提示该 body xpath path 不合法
|
||||
|
||||
#### Scenario: expect operator 类型非法
|
||||
- **WHEN** YAML 中某个 HTTP expect operator 的 match 不是可编译正则字符串,empty/exists 不是布尔值,或 gt/gte/lt/lte 不是有限数字
|
||||
- **THEN** 系统 SHALL 以错误退出,提示对应 operator 配置不合法
|
||||
|
||||
#### Scenario: unknown 字段忽略
|
||||
- **WHEN** YAML 中某个 HTTP target、expect 或 rule 对象包含未知字段,且所有已支持字段均合法
|
||||
- **THEN** 系统 SHALL 忽略未知字段并正常启动
|
||||
|
||||
### Requirement: size 配置解析
|
||||
系统 SHALL 支持使用单位字符串配置读取上限,单位包括 `B`、`KB`、`MB` 和 `GB`。
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
- **THEN** 系统 MUST 同时最多运行 3 个检查,其余检查等待并发槽位释放
|
||||
|
||||
### Requirement: HTTP 拨测执行
|
||||
系统 SHALL 对 `type: http` 的目标执行 HTTP 请求,支持 GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS 方法,并携带 `http.headers` 和 `http.body`。系统 SHALL 支持 `http.ignoreSSL` 配置跳过 SSL 证书校验,支持 `http.maxRedirects` 配置控制重定向行为。
|
||||
系统 SHALL 对 `type: http` 的目标执行 HTTP 请求,支持 GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS 方法,并携带 `http.headers` 和 `http.body`。系统 SHALL 支持 `http.ignoreSSL` 配置跳过 SSL 证书校验,支持 `http.maxRedirects` 配置控制重定向行为。HTTP response body 读取 SHALL 受 `http.maxBodyBytes` 流式限制,重定向跟随 SHALL 释放被跟随响应的 body。
|
||||
|
||||
#### Scenario: 执行 GET 请求
|
||||
- **WHEN** 目标配置 method 为 GET
|
||||
@@ -47,7 +47,15 @@
|
||||
|
||||
#### Scenario: HTTP body 读取上限
|
||||
- **WHEN** HTTP response body 超过该 target 的 maxBodyBytes
|
||||
- **THEN** 系统 MUST 停止读取并记录 `matched=false` 和结构化输出超限错误
|
||||
- **THEN** 系统 MUST 停止继续读取 response body,并记录 `matched=false`、`failure.kind="error"`、`failure.phase="body"` 的结构化输出超限错误
|
||||
|
||||
#### Scenario: HTTP body 大小等于上限
|
||||
- **WHEN** HTTP response body 的字节数等于该 target 的 maxBodyBytes
|
||||
- **THEN** 系统 SHALL 允许该 body 进入后续解码和 expect 校验
|
||||
|
||||
#### Scenario: HTTP body 上限为 0
|
||||
- **WHEN** HTTP target 配置 maxBodyBytes 为 0 且响应体非空
|
||||
- **THEN** 系统 SHALL 停止读取并记录 body 超限错误
|
||||
|
||||
#### Scenario: 忽略 SSL 证书校验
|
||||
- **WHEN** 目标配置 `http.ignoreSSL: true` 且目标 URL 为 HTTPS
|
||||
@@ -63,20 +71,32 @@
|
||||
|
||||
#### Scenario: 配置跟随重定向
|
||||
- **WHEN** 目标配置 `http.maxRedirects: 5` 且服务端返回重定向
|
||||
- **THEN** 系统 SHALL 跟随重定向,最多跟随 5 次
|
||||
- **THEN** 系统 SHALL 跟随重定向,最多跟随 5 次,并在跟随前释放当前重定向响应的 body
|
||||
|
||||
#### Scenario: 超过最大重定向次数
|
||||
- **WHEN** 目标配置 `http.maxRedirects: 1` 且服务端连续返回两次重定向
|
||||
- **THEN** 系统 SHALL 只跟随第一次重定向,并返回第二次重定向响应的状态码和响应头
|
||||
|
||||
#### Scenario: POST 重定向改 GET
|
||||
- **WHEN** POST 请求遇到 301/302 或任意方法请求遇到 303,且系统决定按 GET 跟随重定向
|
||||
- **THEN** 系统 SHALL 移除请求 body,并清理 content-type、content-length 等 body 相关 headers 后发起后续 GET 请求
|
||||
|
||||
#### Scenario: 跨 origin 重定向敏感 header
|
||||
- **WHEN** HTTP 请求跟随重定向到不同 origin
|
||||
- **THEN** 系统 SHALL NOT 将 authorization、cookie 等敏感 headers 转发到新的 origin
|
||||
|
||||
#### Scenario: 响应体编码自动检测
|
||||
- **WHEN** HTTP 响应的 `Content-Type` header 包含 `charset=gbk`
|
||||
- **WHEN** HTTP 响应的 `Content-Type` header 包含 `charset=gbk` 或 `charset="gbk"`
|
||||
- **THEN** 系统 SHALL 使用 GBK 编码解码响应体,而非硬编码 UTF-8
|
||||
|
||||
#### Scenario: 响应体编码回退 UTF-8
|
||||
- **WHEN** HTTP 响应的 `Content-Type` header 未指定 charset
|
||||
- **THEN** 系统 SHALL 使用 UTF-8 编码解码响应体
|
||||
|
||||
#### Scenario: 响应体编码不支持
|
||||
- **WHEN** HTTP 响应的 `Content-Type` header 指定了当前运行时不支持的 charset
|
||||
- **THEN** 系统 SHALL 记录 `matched=false`、`failure.kind="error"`、`failure.phase="body"` 的解码失败结果
|
||||
|
||||
### Requirement: 请求超时控制
|
||||
系统 SHALL 对每次 checker 执行实施超时控制,超时时间使用目标配置的 timeout 值。
|
||||
|
||||
@@ -93,7 +113,7 @@
|
||||
- **THEN** 系统 SHALL 正常记录执行结果并进入 expect 校验
|
||||
|
||||
### Requirement: expect 校验
|
||||
系统 SHALL 在 checker 执行完成后根据目标类型的 expect 配置校验观测结果,校验结果和首个失败原因记入 check result。
|
||||
系统 SHALL 在 checker 执行完成后根据目标类型的 expect 配置校验观测结果,校验结果和首个失败原因记入 check result。HTTP checker 的 `durationMs` SHALL 表示完整 checker 执行耗时,包括重定向、响应体读取、响应体解码和 expect 校验。
|
||||
|
||||
#### Scenario: HTTP 默认状态码
|
||||
- **WHEN** HTTP target 未配置 `expect.status`
|
||||
@@ -119,6 +139,26 @@
|
||||
- **WHEN** HTTP target 配置了有序 `expect.body` 规则数组
|
||||
- **THEN** 系统 SHALL 按数组顺序执行 body 规则,任一失败立即记录 failure 并停止后续规则
|
||||
|
||||
#### Scenario: 校验 HTTP 完整耗时阈值
|
||||
- **WHEN** 目标配置了 `expect.maxDurationMs`,且 HTTP checker 完整执行(含重定向、body 读取、解码和 expect)后的 durationMs 超过阈值
|
||||
- **THEN** 系统 SHALL 判定 duration 不匹配,记录完整 durationMs 和 duration failure
|
||||
|
||||
#### Scenario: HTTP body 前耗时已超阈值
|
||||
- **WHEN** HTTP target 配置了 body 校验和 `expect.maxDurationMs`,且进入 body 读取前的已耗时已超过阈值
|
||||
- **THEN** 系统 SHALL 直接返回 duration failure,且 MUST NOT 读取 response body
|
||||
|
||||
#### Scenario: HTTP body 失败优先于后续 duration 检查
|
||||
- **WHEN** HTTP target 配置了 body 校验和 `expect.maxDurationMs`,body 阶段存在失败,且完整执行后 duration 也超过阈值
|
||||
- **THEN** 系统 SHALL 返回 body 阶段的失败(首个失败为准),durationMs SHALL 记录完整耗时
|
||||
|
||||
#### Scenario: HTTP 慢响应体计入耗时
|
||||
- **WHEN** HTTP target 配置了 body 校验和 `expect.maxDurationMs`,且响应头很快返回但响应体读取导致完整执行耗时超过阈值
|
||||
- **THEN** 系统 SHALL 判定 duration 不匹配并记录完整 durationMs
|
||||
|
||||
#### Scenario: 多条 expect 规则
|
||||
- **WHEN** 目标同时配置状态、duration、元数据和内容规则
|
||||
- **THEN** 系统 SHALL 所有规则全部通过时 matched 为 true,任一不通过则为 false 并记录首个失败原因
|
||||
|
||||
#### Scenario: command 默认 exitCode
|
||||
- **WHEN** command target 未配置 `expect.exitCode`
|
||||
- **THEN** 系统 SHALL 按默认 `exitCode: [0]` 校验命令退出码
|
||||
@@ -127,21 +167,21 @@
|
||||
- **WHEN** command target 配置了有序 `expect.stdout` 规则数组
|
||||
- **THEN** 系统 SHALL 按数组顺序执行 stdout 规则,任一失败立即记录 failure 并停止后续规则
|
||||
|
||||
#### Scenario: 校验耗时阈值
|
||||
- **WHEN** 目标配置了 `expect.maxDurationMs`
|
||||
- **THEN** 系统 SHALL 检查实际 durationMs 是否超过阈值,将匹配结果记录到 matched 字段
|
||||
|
||||
#### Scenario: 多条 expect 规则
|
||||
- **WHEN** 目标同时配置状态、duration、元数据和内容规则
|
||||
- **THEN** 系统 SHALL 所有规则全部通过时 matched 为 true,任一不通过则为 false 并记录首个失败原因
|
||||
|
||||
### Requirement: Body 校验按需解析
|
||||
系统 SHALL 仅在 HTTP target 配置了 body 校验且 status、duration、headers 阶段均通过时才读取并解析响应体,避免不必要的读取和解析开销。
|
||||
系统 SHALL 仅在 HTTP target 配置了 body 校验,且 status、headers 阶段均通过,并且进入 body 前未确定 duration 已失败时才读取并解析响应体,避免不必要的读取和解析开销。HTTP target 未配置 body 校验时,系统 SHALL NOT 读取 response body。
|
||||
|
||||
#### Scenario: status 失败时不读取 body
|
||||
- **WHEN** HTTP target 的 status 阶段不匹配
|
||||
- **THEN** 系统 SHALL 立即返回 matched=false,且 MUST NOT 读取 response body
|
||||
|
||||
#### Scenario: headers 失败时不读取 body
|
||||
- **WHEN** HTTP target 的 status 阶段匹配但 headers 阶段不匹配
|
||||
- **THEN** 系统 SHALL 立即返回 matched=false,且 MUST NOT 读取 response body
|
||||
|
||||
#### Scenario: 进入 body 前 duration 已失败时不读取 body
|
||||
- **WHEN** HTTP target 已配置 `expect.maxDurationMs`,且进入 body 读取前的已耗时已经超过阈值
|
||||
- **THEN** 系统 SHALL 返回 duration failure,且 MUST NOT 读取 response body
|
||||
|
||||
#### Scenario: 仅配置 contains 时不解析 JSON
|
||||
- **WHEN** HTTP target 仅配置 body contains 规则而未配置 json/css/xpath 规则
|
||||
- **THEN** 系统 SHALL 不执行 JSON.parse 或 HTML/XML 解析
|
||||
@@ -150,6 +190,21 @@
|
||||
- **WHEN** HTTP target 配置了 body json 规则但响应体不是合法 JSON
|
||||
- **THEN** 系统 SHALL 判定 matched 为 false,并记录 json 规则对应的 failure.path
|
||||
|
||||
### Requirement: HTTP 运行期错误归属
|
||||
HTTP checker SHALL 将运行期失败归属到实际失败阶段。请求、网络、TLS 和 timeout 错误 SHALL 记录为 request 阶段错误;body 超限、响应体解码失败、响应内容解析失败 SHALL 记录为 body 阶段错误;expect 不匹配 SHALL 记录为对应 mismatch 阶段。
|
||||
|
||||
#### Scenario: 请求错误归属 request
|
||||
- **WHEN** HTTP 请求因为网络、TLS 或 timeout 失败
|
||||
- **THEN** 系统 SHALL 记录 `matched=false`、`failure.kind="error"`、`failure.phase="request"`
|
||||
|
||||
#### Scenario: body 超限归属 body
|
||||
- **WHEN** HTTP response body 超过 maxBodyBytes
|
||||
- **THEN** 系统 SHALL 记录 `failure.kind="error"`、`failure.phase="body"`、`failure.path="body"`
|
||||
|
||||
#### Scenario: body 解析错误归属 body
|
||||
- **WHEN** HTTP response body 已读取,但解码、JSON 解析、CSS 解析或 XPath 解析失败
|
||||
- **THEN** 系统 SHALL 记录 `failure.phase="body"`,且 SHALL NOT 将该失败记录为 request 错误
|
||||
|
||||
### Requirement: 拨测结果记录
|
||||
系统 SHALL 在每次 checker 完成后,将结果写入 SQLite 数据存储,包含 target_id、timestamp、matched、duration_ms、status_detail、failure 字段。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user