Improve request trace upstream diagnostics

This commit is contained in:
fawney19
2026-05-09 10:46:04 +08:00
parent 4cf0de681a
commit 79d07ac79a
33 changed files with 2315 additions and 427 deletions
@@ -45,8 +45,14 @@ vi.mock('../JsonContentPanel.vue', async () => {
return {
default: defineComponent({
name: 'JsonContentPanelStub',
setup() {
return () => h('div')
props: {
data: {
type: null,
default: null,
},
},
setup(props) {
return () => h('pre', JSON.stringify(props.data))
},
}),
}
@@ -321,4 +327,81 @@ describe('HorizontalRequestTimeline', () => {
const requestPathCode = root.querySelector<HTMLElement>('.request-path-code')
expect(requestPathCode?.textContent).toContain('/v1beta/models/gemini-2.5-pro:generateContent?alt=sse')
})
it('shows request path from trace payload', async () => {
const trace: RequestTrace = {
...buildTrace([
buildCandidate({
id: 'cand-trace-path',
provider_id: 'provider-path',
provider_name: 'Provider Path',
key_id: 'key-path',
key_name: 'Path Key',
candidate_index: 0,
status: 'failed',
}),
]),
request_path: '/v1/images/generations',
}
const root = mountTimeline(trace)
await nextTick()
expect(root.textContent).toContain('请求路径')
const requestPathCode = root.querySelector<HTMLElement>('.request-path-code')
expect(requestPathCode?.textContent).toContain('/v1/images/generations')
})
it('shows upstream response JSON inside the error block on trace nodes', async () => {
const trace = buildTrace([
buildCandidate({
id: 'cand-upstream-response',
provider_id: 'provider-upstream',
provider_name: 'Provider Upstream',
key_id: 'key-upstream',
key_name: 'Upstream Key',
candidate_index: 0,
status: 'failed',
error_message: 'execution runtime stream returned non-success status 302',
extra_data: {
upstream_response: {
status_code: 302,
headers: { location: '/' },
},
error_flow: {
source: 'upstream_response',
status_code: 302,
classification: 'use_default',
decision: 'use_default',
propagation: 'none',
retryable: false,
safe_to_expose: false,
message: 'execution runtime stream returned non-success status 302',
},
client_response: {
status_code: 502,
headers: { 'content-type': 'application/json' },
},
},
}),
])
const root = mountTimeline(trace)
await nextTick()
expect(root.textContent).toContain('错误信息')
expect(root.textContent).toContain('HTTP 302')
expect(root.textContent).not.toContain('上游返回非成功状态 302')
expect(root.querySelector('.error-block .error-json')?.textContent).toContain('"status_code":302')
expect(root.querySelector('.error-block .error-json')?.textContent).toContain('"headers"')
expect(root.textContent).not.toContain('上游真实响应')
expect(root.textContent).not.toContain('execution runtime stream returned non-success status 302')
expect(root.textContent).not.toContain('真实请求错误')
expect(root.textContent).not.toContain('返回客户端响应')
expect(root.textContent).not.toContain('上游响应')
expect(root.textContent).not.toContain('默认处理')
expect(root.textContent).not.toContain('none')
expect(root.textContent).not.toContain('不再重试')
expect(root.textContent).not.toContain('该错误被标记为敏感上游错误')
})
})