Bug 描述
@eric8810/catcher-napi-http 手写 TS 类型 (ts/types.ts) 中 #[napi(object)] 结构体的字段名使用了 Rust snake_case,但 NAPI-RS 自动将这些字段转为 JS camelCase。导致:
- 输入类:
RequestOptions.content_type 赋值后被 NAPI-RS 忽略(Content-Type header 不发送)
- 输出类:
HttpResponse.elapsed_ms / Metrics.http_requests 等字段读取到 undefined
根因
NAPI-RS 自动将 Rust snake_case 字段转为 JS camelCase。手写 ts/types.ts 与自动生成的 index.d.ts 不一致。
受影响的类型(3 个)
1. RequestOptions(输入)— 导致 Content-Type 丢失
| Rust 字段 |
NAPI-RS 生成 (index.d.ts) |
手写 ts/types.ts(错误) |
content_type |
contentType |
content_type |
timeout_ms |
timeoutMs |
timeout_ms |
影响:用户传 { content_type: 'application/json' } → NAPI-RS 找 contentType → 找不到 → Rust 收到 None → Content-Type header 不发送 → 服务端返回 500。
2. HttpResponse(输出)— elapsed_ms 读不到
| Rust 字段 |
NAPI-RS 生成 (index.d.ts) |
手写 ts/types.ts(错误) |
elapsed_ms |
elapsedMs |
elapsed_ms |
影响:resp.elapsed_ms 返回 undefined。
3. Metrics(输出)— 全部 10 个字段读不到
| Rust 字段 |
NAPI-RS 生成 |
手写(错误) |
http_requests |
httpRequests |
http_requests |
http_success_rate |
httpSuccessRate |
http_success_rate |
http_avg_latency_us |
httpAvgLatencyUs |
http_avg_latency_us |
http_retries |
httpRetries |
http_retries |
ws_connect_success_rate |
wsConnectSuccessRate |
ws_connect_success_rate |
ws_disconnects |
wsDisconnects |
ws_disconnects |
ws_messages_sent |
wsMessagesSent |
ws_messages_sent |
ws_messages_received |
wsMessagesReceived |
ws_messages_received |
cb_open_count |
cbOpenCount |
cb_open_count |
queue_timeouts |
queueTimeouts |
queue_timeouts |
影响:metrics.http_requests 等全部返回 undefined。
不受影响的类型
HttpClientConfig — 通过 JSON 字符串传入构造函数,serde 有 #[serde(alias)] 兼容两种命名
SseClientConfig — 同上,JSON 字符串 + serde
catcher-napi-ws — 无 #[napi(object)] 结构体,全部通过 JSON 字符串通信,无此问题
修复
ts/types.ts — 所有 #[napi(object)] 对应的 interface 字段名改为 camelCase
ts/client.ts — RequestOptions 添加 normalizeOptions() 归一化函数,向后兼容旧 snake_case 写法
临时解决方案
在修复发布前:
// Content-Type 临时方案:放到 headers 里
client.post(url, body, {
headers: { 'Content-Type': 'application/json' },
})
// Metrics / Response:直接用 camelCase 访问(绕过 TS 类型检查)
(resp as any).elapsedMs
(metrics as any).httpRequests
Bug 描述
@eric8810/catcher-napi-http手写 TS 类型 (ts/types.ts) 中#[napi(object)]结构体的字段名使用了 Rust snake_case,但 NAPI-RS 自动将这些字段转为 JS camelCase。导致:RequestOptions.content_type赋值后被 NAPI-RS 忽略(Content-Typeheader 不发送)HttpResponse.elapsed_ms/Metrics.http_requests等字段读取到undefined根因
NAPI-RS 自动将 Rust
snake_case字段转为 JScamelCase。手写ts/types.ts与自动生成的index.d.ts不一致。受影响的类型(3 个)
1.
RequestOptions(输入)— 导致 Content-Type 丢失index.d.ts)ts/types.ts(错误)content_typecontentTypecontent_typetimeout_mstimeoutMstimeout_ms影响:用户传
{ content_type: 'application/json' }→ NAPI-RS 找contentType→ 找不到 → Rust 收到None→Content-Typeheader 不发送 → 服务端返回 500。2.
HttpResponse(输出)— elapsed_ms 读不到index.d.ts)ts/types.ts(错误)elapsed_mselapsedMselapsed_ms影响:
resp.elapsed_ms返回undefined。3.
Metrics(输出)— 全部 10 个字段读不到http_requestshttpRequestshttp_requestshttp_success_ratehttpSuccessRatehttp_success_ratehttp_avg_latency_ushttpAvgLatencyUshttp_avg_latency_ushttp_retrieshttpRetrieshttp_retriesws_connect_success_ratewsConnectSuccessRatews_connect_success_ratews_disconnectswsDisconnectsws_disconnectsws_messages_sentwsMessagesSentws_messages_sentws_messages_receivedwsMessagesReceivedws_messages_receivedcb_open_countcbOpenCountcb_open_countqueue_timeoutsqueueTimeoutsqueue_timeouts影响:
metrics.http_requests等全部返回undefined。不受影响的类型
HttpClientConfig— 通过 JSON 字符串传入构造函数,serde 有#[serde(alias)]兼容两种命名SseClientConfig— 同上,JSON 字符串 + serdecatcher-napi-ws— 无#[napi(object)]结构体,全部通过 JSON 字符串通信,无此问题修复
ts/types.ts— 所有#[napi(object)]对应的 interface 字段名改为 camelCasets/client.ts—RequestOptions添加normalizeOptions()归一化函数,向后兼容旧 snake_case 写法临时解决方案
在修复发布前: