mirror of
https://github.com/Yuyi-Oak/BlueArchiveToolkit.git
synced 2026-09-18 14:14:53 +08:00
feat(official-sync): 下载失败携带类型化错误码
用类型化错误(不做 message 匹配)把资源下载失败归到准确的 BAT-ERR 码:
- curl_transfer:CurlFailureKind::error_code() 映射到网络域码(403→300001、
404→300002、5xx→300005、dns/connect/timeout/tls/interrupted→30001x、
proxy→310001、其余→300015);CurlRetryError::final_error_code() 取末次失败的码。
- official_download:新增 pub DownloadError { code, message },From<String>→internal,
Display/Error;pull_* 的返回类型由 String 改为 DownloadError,内部 String 错误经
From 归 internal,下载失败边界带 pull_one 的 error_code(),非官方 URL 带
non_official_url(300030)。
- official_update:pull 错误改用 anyhow::Error::new 保留 DownloadError 类型。
- 任务 worker:downcast DownloadError 取 code 写入任务记录的 error(失败不再一律
900001),非下载失败仍归 internal。
验证:新增 kind→code 映射单测;pull 404 测试断言 DownloadError.code()==HTTP_NOT_FOUND;
lib/core 全量测试通过,clippy --all-targets 干净。
范围说明:本次覆盖资源下载路径;launcher/metadata 拉取(official_launcher)的网络
失败仍归 internal,可按同一模式后续接入。
对应 issue #1(错误码细分映射,第一批)。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -229,6 +229,26 @@ impl CurlFailureKind {
|
||||
}
|
||||
}
|
||||
|
||||
/// 映射到统一错误码(网络域 3xx;代理故障 310001)。
|
||||
pub(crate) fn error_code(&self) -> bat_core::ErrorCode {
|
||||
use bat_core::ErrorCode;
|
||||
match self {
|
||||
Self::HttpForbidden => ErrorCode::HTTP_FORBIDDEN,
|
||||
Self::HttpNotFound => ErrorCode::HTTP_NOT_FOUND,
|
||||
Self::HttpClientError => ErrorCode::HTTP_CLIENT_ERROR,
|
||||
Self::HttpTooManyRequests => ErrorCode::HTTP_TOO_MANY_REQUESTS,
|
||||
Self::HttpServerError => ErrorCode::HTTP_SERVER_ERROR,
|
||||
Self::Dns => ErrorCode::NETWORK_DNS,
|
||||
Self::Connect => ErrorCode::NETWORK_CONNECT,
|
||||
Self::Timeout => ErrorCode::NETWORK_TIMEOUT,
|
||||
Self::Tls => ErrorCode::NETWORK_TLS,
|
||||
Self::Interrupted => ErrorCode::NETWORK_INTERRUPTED,
|
||||
Self::Proxy => ErrorCode::PROXY_FAILURE,
|
||||
Self::HttpUnknown | Self::Network | Self::Unknown => ErrorCode::NETWORK_OTHER,
|
||||
Self::ProcessFailed => ErrorCode::INTERNAL,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn is_retryable(&self) -> bool {
|
||||
match self {
|
||||
// 代理故障(认证失败、代理主机解析/连接失败)多为配置错误,per-URL 层
|
||||
@@ -346,6 +366,11 @@ impl CurlRetryError {
|
||||
self.final_failure().map(|failure| failure.kind.as_str())
|
||||
}
|
||||
|
||||
pub(crate) fn final_error_code(&self) -> Option<bat_core::ErrorCode> {
|
||||
self.final_failure()
|
||||
.map(|failure| failure.kind.error_code())
|
||||
}
|
||||
|
||||
pub(crate) fn final_http_status(&self) -> Option<u16> {
|
||||
self.final_failure().and_then(|failure| failure.http_status)
|
||||
}
|
||||
@@ -547,6 +572,22 @@ mod tests {
|
||||
assert!(!failure.retryable());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn failure_kind_maps_to_error_code() {
|
||||
use bat_core::ErrorCode;
|
||||
assert_eq!(
|
||||
CurlFailureKind::HttpForbidden.error_code().id(),
|
||||
ErrorCode::HTTP_FORBIDDEN.id()
|
||||
);
|
||||
assert_eq!(
|
||||
CurlFailureKind::HttpNotFound.error_code().id(),
|
||||
"BAT-ERR-300002"
|
||||
);
|
||||
assert_eq!(CurlFailureKind::Proxy.error_code().id(), "BAT-ERR-310001");
|
||||
assert_eq!(CurlFailureKind::Timeout.error_code().id(), "BAT-ERR-300012");
|
||||
assert_eq!(CurlFailureKind::Network.error_code().id(), "BAT-ERR-300015");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_http_status_anchors_on_curl_error_context() {
|
||||
// 状态码前出现无关三位数字(如端口 443)时,仍从 "error" 之后取真正的状态码。
|
||||
|
||||
Reference in New Issue
Block a user