Skip to content

fix: napi-http TS 类型 snake_case/camelCase 不匹配 — RequestOptions / HttpResponse / Metrics 字段名错误 #3

Description

@eric8810

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 收到 NoneContent-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 字符串通信,无此问题

修复

  1. ts/types.ts — 所有 #[napi(object)] 对应的 interface 字段名改为 camelCase
  2. ts/client.tsRequestOptions 添加 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions