Tripo 启动检查连解析后的字段一起校验,不再只看环境变量原文

- api-server tripo3d/provider.rs:`validate_tripo_startup_config` 在原有 env 校验之后,追加对 `AppConfig` 字段值的校验(零超时、重试越界),与请求期 `tripo_settings` 读的是同一对字段
- 用例:新增 `startup_rejects_invalid_parsed_fields_from_any_construction_path`,覆盖「直接构造的配置带着非法值也不能通过启动检查」
This commit is contained in:
2026-09-24 19:54:08 +08:00
parent 6e081676f0
commit d04f74bd34
@@ -37,13 +37,35 @@ pub(crate) struct TripoStartupValues<'a> {
}
/// 读取原始 env 后校验;返回值直接作为启动失败原因展示给运维。
///
/// 只看环境变量是不够的:真正发请求时用的是 [`AppConfig`] 上的字段值,而配置文件、测试与
/// 代码里直接构造的配置都不经过 `from_env`,非法值(零超时、越界重试)能带着它一路通过
/// 启动检查,直到请求期才以 503 暴露。因此这里把解析后的字段也一并校验,两处用的是同一份值。
pub(crate) fn validate_tripo_startup_config(config: &AppConfig) -> Result<(), String> {
validate_tripo_startup_values(TripoStartupValues {
base_url: config.tripo_base_url.as_str(),
api_key: config.tripo_api_key.as_deref(),
request_timeout_ms: env::var(TRIPO_REQUEST_TIMEOUT_MS_ENV).ok().as_deref(),
retries: env::var(TRIPO_RETRIES_ENV).ok().as_deref(),
})
})?;
validate_tripo_startup_fields(config)
}
/// 解析后的两个运行旋钮:与 [`tripo_settings`] 读的是同一对字段。
fn validate_tripo_startup_fields(config: &AppConfig) -> Result<(), String> {
if config.tripo_request_timeout_ms == 0 {
return Err(format!(
"{TRIPO_REQUEST_TIMEOUT_MS_ENV} 必须大于 0:零超时在 timeout 与 reqwest \
两处含义相反,放它进来只会得到指向错误方向的报错。"
));
}
if config.tripo_retries > TRIPO_MAX_RETRIES {
return Err(format!(
"{TRIPO_RETRIES_ENV} 不能超过 {TRIPO_MAX_RETRIES},当前为 {}。",
config.tripo_retries
));
}
Ok(())
}
/// 纯函数形态的校验,便于用例直接覆盖各种坏配置。
@@ -268,6 +290,30 @@ mod tests {
);
}
/// 启动检查必须看配置对象里的值,不只是环境变量原文:否则直接构造的非法配置
/// (零超时、越界重试)能通过启动检查,直到请求期才以 503 暴露。
#[test]
fn startup_rejects_invalid_parsed_fields_from_any_construction_path() {
let mut config = AppConfig::default();
config.tripo_base_url = "https://openapi.tripo3d.com/v3".to_string();
config.tripo_api_key = Some("test-key".to_string());
assert!(validate_tripo_startup_config(&config).is_ok());
config.tripo_request_timeout_ms = 0;
let zero_timeout = validate_tripo_startup_config(&config)
.expect_err("零超时必须拒绝启动,即使它不是从环境变量读来的");
assert!(
zero_timeout.contains("TRIPO_REQUEST_TIMEOUT_MS"),
"{zero_timeout}"
);
config.tripo_request_timeout_ms = crate::config::DEFAULT_TRIPO_REQUEST_TIMEOUT_MS;
config.tripo_retries = TRIPO_MAX_RETRIES + 1;
let too_many = validate_tripo_startup_config(&config)
.expect_err("越界重试必须拒绝启动,即使它不是从环境变量读来的");
assert!(too_many.contains("TRIPO_RETRIES"), "{too_many}");
}
#[test]
fn startup_accepts_declared_knobs_at_their_limits() {
let mut values = startup_values("https://openapi.tripo3d.com/v3", Some("key"));