M48 复审的中危 finding:error.type 里的散文经 trace.UpstreamError 原样出镜,
因为守卫加在调用方(M46 的 model/voice 两处),构造函数自己不套守卫 ——
任何新调用点默认不安全,httpclient / vision / embedding / weixin 四条出口一直漏。
- trace.UpstreamError 构造时对 error.code / error.type 各走一次 ErrorToken
([A-Za-z0-9_.-]{<=64},不合规即空串):默认安全,不是可选加固。
- 构造后注入这条窄路收进 UpstreamErrorInfo.SetCode / SetType(同一道守卫),
供 DashScope 顶层 code 与 Anthropic 流内 error.type 两处使用 —— 调用方不再
各抄一份 ErrorToken。
- 删除因此冗余的调用方守卫:model.providerUpstreamError 与
voice.dashscopeOKBodyError。保留 voice 的 request_id 守卫(它不是 code/type,
构造函数看不见)。
- 四条漏的出口一行没改,只加用例证明守卫上移后自动安全;摘掉构造函数守卫时
四条用例 + model/voice 旧用例同时变红。
42 lines
1.8 KiB
Go
42 lines
1.8 KiB
Go
package voice
|
||
|
||
// 本文件是 M49 的**出口回归探针**:DashScope 的「HTTP 200 但业务失败」收口里,
|
||
// error.code / error.type 的守卫已经上移进 trace.UpstreamError —— 本包那处调用点的
|
||
// 重复守卫已删除,因此这里的断言直接钉在**构造函数**上(摘掉构造函数的守卫就变红)。
|
||
//
|
||
// 与它相邻的一条(TestDashscopeTTS_Non200DropsFreeTextCode)钉的是另一件事:
|
||
// DashScope 的 4xx 把错误码放在**顶层** code(构造函数看不见),那一处靠
|
||
// UpstreamErrorInfo.SetCode 注入,守卫仍在。两条合起来覆盖这一族的两个面。
|
||
|
||
import (
|
||
"errors"
|
||
"strings"
|
||
"testing"
|
||
)
|
||
|
||
// TestDashscopeOKBodyError_DropsFreeTextErrorCode 200 报文的 error.code / error.type
|
||
// 里带散文(TTS 场景下可能是她要念的台词被回显)⇒ 两个字段整体消失,而 status=200
|
||
// 与 body_bytes(体积摘要)仍在。
|
||
func TestDashscopeOKBodyError_DropsFreeTextErrorCode(t *testing.T) {
|
||
t.Parallel()
|
||
const prose = "Invalid value: '她刚才说的那句话'"
|
||
body := []byte(`{"error":{"code":"` + prose + `","type":"` + prose + `"}}`)
|
||
|
||
err := dashscopeOKBodyError("https://dashscope.example.com/api/v1/services/audio/tts", body)
|
||
if !errors.Is(err, ErrProviderFailed) {
|
||
t.Fatalf("err = %v, want ErrProviderFailed(熔断口径不变)", err)
|
||
}
|
||
msg := err.Error()
|
||
if strings.Contains(msg, "她刚才说的那句话") {
|
||
t.Fatalf("上游 error.code/type 里的散文进了错误:%v", msg)
|
||
}
|
||
if strings.Contains(msg, " code=") || strings.Contains(msg, " type=") {
|
||
t.Fatalf("非令牌形状的 code/type 没有被丢弃:%v", msg)
|
||
}
|
||
for _, want := range []string{"status=200", "body_bytes="} {
|
||
if !strings.Contains(msg, want) {
|
||
t.Fatalf("错误里缺少 %q(诊断面不能一起丢):%v", want, msg)
|
||
}
|
||
}
|
||
}
|