Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"packages/catcher-core-ts": "0.3.18",
"packages/catcher-http-ts": "0.3.18",
"packages/catcher-ws-ts": "0.3.18",
"packages/catcher-web": "0.3.18",
"packages/catcher-napi-http": "0.3.18",
"packages/catcher-napi-ws": "0.3.18",
"packages/catcher-core": "0.3.18",
"packages/catcher-dns": "0.3.18",
"packages/catcher-http": "0.3.18",
"packages/catcher-ws": "0.3.18",
"packages/catcher-ffi": "0.3.18",
"packages/catcher-uniffi": "0.3.18",
"packages/catcher_core": "0.3.18"
"packages/catcher-core-ts": "0.3.19",
"packages/catcher-http-ts": "0.3.19",
"packages/catcher-ws-ts": "0.3.19",
"packages/catcher-web": "0.3.19",
"packages/catcher-napi-http": "0.3.19",
"packages/catcher-napi-ws": "0.3.19",
"packages/catcher-core": "0.3.19",
"packages/catcher-dns": "0.3.19",
"packages/catcher-http": "0.3.19",
"packages/catcher-ws": "0.3.19",
"packages/catcher-ffi": "0.3.19",
"packages/catcher-uniffi": "0.3.19",
"packages/catcher_core": "0.3.19"
}
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

All notable changes to this project will be documented in this file. See [release-please](https://github.com/googleapis/release-please) for automated management.

## 0.3.19 (2026-08-13)

> 修复 N-API HTTP 传输异常被压缩成 `GenericFailure`、导致上层无法识别失败阶段和最终重试原因的问题。

### 🐛 Bug Fixes

- **结构化传输异常**:连接拒绝、DNS、TLS、连接超时、请求超时及其他传输失败均提供稳定的 `code`、`phase`、`retryable` 和白名单 `details`。
- **保留重试根因**:`RETRY_EXHAUSTED` 记录实际执行总次数,并在 `details.lastError` 中保留最终结构化异常,不再只保存字符串。
- **N-API 错误类型**:JavaScript 调用方收到导出的 `CatcherError` / `HttpError`,同时保留旧版 HTTP 文本错误兼容解析。
- **安全诊断信息**:原生错误链序列化前移除请求 URL,避免查询参数和 token 泄漏。
- **跨平台契约覆盖**:CI 在 Linux、macOS 和 Windows 上验证非法配置、连接拒绝、重试耗尽和请求超时契约。

### 📦 Packaging

- 所有 npm、Rust、NAPI 和 Flutter 包统一同步到 `0.3.19`。

## 0.3.18 (2026-08-07)

> 修复代理/VPN/网络路径变化后服务端返回 HTTP 421(Misdirected Request)时客户端持续失败的问题,并为 NAPI 调用方提供结构化 HTTP 状态错误。
Expand Down
29 changes: 29 additions & 0 deletions docs/releases/0.3.19.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Catcher 0.3.19

发布日期:2026-08-13

## 重点修复

本版本修复 N-API HTTP 传输异常被折叠为 `GenericFailure` 的问题。上层现在可以直接依据稳定字段判断异常类型,而不需要解析平台相关的错误文本。

结构化异常字段包括:

- `code`:例如 `CONNECTION_ERROR`、`REQUEST_TIMEOUT`、`RETRY_EXHAUSTED`
- `phase`:例如 `connect`、`request`、`response`
- `retryable`:当前异常是否适合重试
- `details`:经过白名单限制的状态、超时、主机和原因信息

重试耗尽时,`details.attempts` 表示包含首次请求在内的实际执行总次数,`details.lastError` 保留最后一次请求的完整结构化异常。

## 安全与兼容性

- 原生错误链在跨越 N-API 边界前移除请求 URL,避免查询参数泄漏。
- HTTP 状态错误继续以 `HttpError` 暴露 `status` 和 `body`。
- 旧版原生 HTTP 文本错误仍保留兼容解析。
- HTTP 421 的连接池恢复行为与 0.3.18 保持不变。

## 验证

- Rust workspace check、clippy 和测试
- TypeScript build、typecheck 和测试
- Linux、macOS、Windows N-API HTTP 错误契约测试
18 changes: 9 additions & 9 deletions packages/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/catcher-core-ts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eric8810/catcher-core",
"version": "0.3.18",
"version": "0.3.19",
"description": "Catcher shared type definitions — zero runtime dependencies",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/catcher-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "catcher-core"
version = "0.3.18"
version = "0.3.19"
edition = "2021"
description = "Shared core types and errors for catcher — zero I/O dependencies"
license = "MIT"
Expand Down
4 changes: 2 additions & 2 deletions packages/catcher-dns/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "catcher-dns"
version = "0.3.18"
version = "0.3.19"
edition = "2021"
description = "Shared DNS resolver and system proxy detection for catcher"
license = "MIT"
Expand All @@ -13,7 +13,7 @@ reqwest-resolver = ["dep:reqwest"]
system-proxy = ["dep:proxy_cfg"]

[dependencies]
catcher-core = { path = "../catcher-core", version = "0.3.18" }
catcher-core = { path = "../catcher-core", version = "0.3.19" }
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["net", "rt", "time", "macros"] }
parking_lot = "0.12"
Expand Down
14 changes: 7 additions & 7 deletions packages/catcher-ffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "catcher-ffi"
version = "0.3.18"
version = "0.3.19"
edition = "2021"
description = "Unified C ABI library for catcher — links HTTP + WS + codec into a single .so/.dylib"
license = "MIT"
Expand All @@ -11,15 +11,15 @@ crate-type = ["cdylib", "lib"]
name = "catcher_ffi"

[dependencies]
catcher-core = { path = "../catcher-core", version = "0.3.18" }
catcher-http = { path = "../catcher-http", version = "0.3.18" }
catcher-ws = { path = "../catcher-ws", version = "0.3.18" }
catcher-core = { path = "../catcher-core", version = "0.3.19" }
catcher-http = { path = "../catcher-http", version = "0.3.19" }
catcher-ws = { path = "../catcher-ws", version = "0.3.19" }
serde_json = "1"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }

[dev-dependencies]
catcher-core = { path = "../catcher-core", version = "0.3.18" }
catcher-http = { path = "../catcher-http", version = "0.3.18" }
catcher-ws = { path = "../catcher-ws", version = "0.3.18" }
catcher-core = { path = "../catcher-core", version = "0.3.19" }
catcher-http = { path = "../catcher-http", version = "0.3.19" }
catcher-ws = { path = "../catcher-ws", version = "0.3.19" }
wiremock = "0.6"
tokio-test = "0.4"
2 changes: 1 addition & 1 deletion packages/catcher-http-ts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eric8810/catcher-http",
"version": "0.3.18",
"version": "0.3.19",
"description": "Catcher HTTP client — resilient transport with retry, circuit breaker, priority scheduling",
"type": "module",
"main": "./dist/index.js",
Expand Down
6 changes: 3 additions & 3 deletions packages/catcher-http/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "catcher-http"
version = "0.3.18"
version = "0.3.19"
edition = "2021"
description = "HTTP client for catcher — resilient transport with retry, circuit breaker, priority scheduling"
license = "MIT"
Expand All @@ -15,8 +15,8 @@ napi = ["dep:napi", "dep:napi-derive"]
system-proxy = ["catcher-dns/system-proxy"]

[dependencies]
catcher-core = { path = "../catcher-core", version = "0.3.18" }
catcher-dns = { path = "../catcher-dns", version = "0.3.18", default-features = false }
catcher-core = { path = "../catcher-core", version = "0.3.19" }
catcher-dns = { path = "../catcher-dns", version = "0.3.19", default-features = false }

# ── 异步运行时 ──
tokio = { version = "1", features = ["sync", "time", "net", "io-util", "macros"] }
Expand Down
6 changes: 3 additions & 3 deletions packages/catcher-napi-http/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "catcher-napi-http"
version = "0.3.18"
version = "0.3.19"
edition = "2021"
description = "catcher HTTP napi-rs Node.js native bindings"
license = "MIT"
Expand All @@ -9,8 +9,8 @@ license = "MIT"
crate-type = ["cdylib"]

[dependencies]
catcher-core = { path = "../catcher-core", version = "0.3.18" }
catcher-http = { path = "../catcher-http", version = "0.3.18", features = ["system-proxy"] }
catcher-core = { path = "../catcher-core", version = "0.3.19" }
catcher-http = { path = "../catcher-http", version = "0.3.19", features = ["system-proxy"] }
napi = { version = "2", default-features = false, features = ["napi4", "tokio_rt", "serde-json"] }
napi-derive = "2"
serde = { version = "1", features = ["derive"] }
Expand Down
2 changes: 1 addition & 1 deletion packages/catcher-napi-http/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eric8810/catcher-napi-http",
"version": "0.3.18",
"version": "0.3.19",
"description": "catcher HTTP native addon for Node.js via napi-rs",
"main": "dist/client.js",
"types": "dist/client.d.ts",
Expand Down
4 changes: 2 additions & 2 deletions packages/catcher-napi-ws/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "catcher-napi-ws"
version = "0.3.18"
version = "0.3.19"
edition = "2021"
description = "catcher WebSocket napi-rs Node.js native bindings"
license = "MIT"
Expand All @@ -9,7 +9,7 @@ license = "MIT"
crate-type = ["cdylib"]

[dependencies]
catcher-ws = { path = "../catcher-ws", version = "0.3.18", features = ["rustls-tls", "system-proxy"] }
catcher-ws = { path = "../catcher-ws", version = "0.3.19", features = ["rustls-tls", "system-proxy"] }
napi = { version = "2", default-features = false, features = ["napi4", "tokio_rt", "serde-json"] }
napi-derive = "2"
serde_json = "1"
Expand Down
2 changes: 1 addition & 1 deletion packages/catcher-napi-ws/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eric8810/catcher-napi-ws",
"version": "0.3.18",
"version": "0.3.19",
"description": "catcher WebSocket native addon for Node.js via napi-rs",
"main": "dist/client.js",
"types": "dist/client.d.ts",
Expand Down
2 changes: 1 addition & 1 deletion packages/catcher-test-support/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "catcher-test-support"
version = "0.3.18"
version = "0.3.19"
edition = "2021"
publish = false

Expand Down
8 changes: 4 additions & 4 deletions packages/catcher-uniffi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "catcher-uniffi"
version = "0.3.18"
version = "0.3.19"
edition = "2021"
description = "UniFFI bindings for catcher — auto-generates Swift + Kotlin from Rust API"
license = "MIT"
Expand All @@ -11,9 +11,9 @@ crate-type = ["cdylib", "staticlib"]
name = "catcher_uniffi"

[dependencies]
catcher-core = { path = "../catcher-core", version = "0.3.18" }
catcher-http = { path = "../catcher-http", version = "0.3.18" }
catcher-ws = { path = "../catcher-ws", version = "0.3.18" }
catcher-core = { path = "../catcher-core", version = "0.3.19" }
catcher-http = { path = "../catcher-http", version = "0.3.19" }
catcher-ws = { path = "../catcher-ws", version = "0.3.19" }
uniffi = { version = "0.28", features = ["cli"] }
serde_json = "1"
thiserror = "1"
Expand Down
2 changes: 1 addition & 1 deletion packages/catcher-web/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eric8810/catcher-web",
"version": "0.3.18",
"version": "0.3.19",
"description": "Catcher HTTP client for browsers — fetch-based with retry, circuit breaker & priority queue",
"type": "module",
"main": "./dist/index.js",
Expand Down
2 changes: 1 addition & 1 deletion packages/catcher-ws-ts/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@eric8810/catcher-ws",
"version": "0.3.18",
"version": "0.3.19",
"description": "Catcher WebSocket client — resilient reconnect, multi-endpoint racing, msgpack codec",
"type": "module",
"main": "./dist/index.js",
Expand Down
6 changes: 3 additions & 3 deletions packages/catcher-ws/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "catcher-ws"
version = "0.3.18"
version = "0.3.19"
edition = "2021"
description = "WebSocket client for catcher — resilient reconnect, heartbeat, multi-endpoint racing"
license = "MIT"
Expand All @@ -12,8 +12,8 @@ rustls-tls = ["yawc/rustls-ring", "reqwest/rustls"]
system-proxy = ["catcher-dns/system-proxy"]

[dependencies]
catcher-core = { path = "../catcher-core", version = "0.3.18" }
catcher-dns = { path = "../catcher-dns", version = "0.3.18", features = ["reqwest-resolver"] }
catcher-core = { path = "../catcher-core", version = "0.3.19" }
catcher-dns = { path = "../catcher-dns", version = "0.3.19", features = ["reqwest-resolver"] }
tokio = { version = "1", features = ["rt-multi-thread", "sync", "time", "net", "io-util", "macros"] }
futures-util = "0.3"
backon = "1"
Expand Down
2 changes: 1 addition & 1 deletion packages/catcher_core/ios/catcher_core.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'catcher_core'
s.version = '0.3.18'
s.version = '0.3.19'
s.summary = 'Resilient HTTP/WebSocket client backed by Rust core for Flutter.'
s.description = <<-DESC
Resilient HTTP/WebSocket client backed by Rust core for Flutter.
Expand Down
2 changes: 1 addition & 1 deletion packages/catcher_core/macos/catcher_core.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'catcher_core'
s.version = '0.3.18'
s.version = '0.3.19'
s.summary = 'Resilient HTTP/WebSocket client backed by Rust core for Flutter.'
s.description = <<-DESC
Resilient HTTP/WebSocket client backed by Rust core for Flutter.
Expand Down
2 changes: 1 addition & 1 deletion packages/catcher_core/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: catcher_core
version: 0.3.18
version: 0.3.19
description: Resilient HTTP/WebSocket client backed by Rust core for Flutter
repository: https://github.com/eric8810/catcher
issue_tracker: https://github.com/eric8810/catcher/issues
Expand Down
Loading
Loading