fix(claim): 透出 affiliate_dash 上游错误,便于排查提交 UID 失败
上游 4xx 不再一律打成 502 兜底文案;affiliate_dash 依赖错误优先展示真实 message。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -95,18 +95,20 @@ export async function affiliateDashRequest(input: {
|
||||
logExternalHttpPacket('[affiliate-dash/http]', 'HTTP 响应失败', responsePacket, {
|
||||
level: 'warn',
|
||||
})
|
||||
throw createHttpError(
|
||||
summarizeAffiliateDashMessage(json) || `affiliate-dash 请求失败: HTTP ${response.status}`,
|
||||
{
|
||||
statusCode: 502,
|
||||
errorCode: 'affiliate_dash_http_failed',
|
||||
context: {
|
||||
status: response.status,
|
||||
message: summarizeAffiliateDashMessage(json),
|
||||
body: text,
|
||||
},
|
||||
const upstreamMessage =
|
||||
summarizeAffiliateDashMessage(json) || `affiliate-dash 请求失败: HTTP ${response.status}`
|
||||
// 上游 4xx 透传状态码,便于领取页展示真实原因;5xx 仍归一为 502。
|
||||
const statusCode =
|
||||
response.status >= 400 && response.status < 500 ? response.status : 502
|
||||
throw createHttpError(upstreamMessage, {
|
||||
statusCode,
|
||||
errorCode: 'affiliate_dash_http_failed',
|
||||
context: {
|
||||
status: response.status,
|
||||
message: summarizeAffiliateDashMessage(json),
|
||||
body: text,
|
||||
},
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
if (!isAffiliateDashSuccessResponse(json)) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import test from 'node:test'
|
||||
|
||||
import { resolveRouteErrorLogLevel } from './http.js'
|
||||
import { buildErrorPayload, createHttpError, resolveRouteErrorLogLevel } from './http.js'
|
||||
|
||||
test('expected worker session expiry is debug-level', () => {
|
||||
assert.equal(
|
||||
@@ -14,3 +14,22 @@ test('expected worker session expiry is debug-level', () => {
|
||||
)
|
||||
assert.equal(resolveRouteErrorLogLevel({ statusCode: 500, errorCode: 'internal_error' }), 'error')
|
||||
})
|
||||
|
||||
test('affiliate_dash errors surface upstream message even when mapped to 502', () => {
|
||||
const error = createHttpError('乐玩开放平台 AccessKey 或 SecretKey 未配置', {
|
||||
statusCode: 502,
|
||||
errorCode: 'affiliate_dash_http_failed',
|
||||
})
|
||||
const payload = buildErrorPayload(error, '提交 UID 失败')
|
||||
assert.equal(payload.msg, '乐玩开放平台 AccessKey 或 SecretKey 未配置')
|
||||
assert.equal(payload.errorCode, 'affiliate_dash_http_failed')
|
||||
})
|
||||
|
||||
test('generic 5xx still uses fallback message', () => {
|
||||
const error = createHttpError('secret internal boom', {
|
||||
statusCode: 500,
|
||||
errorCode: 'internal_error',
|
||||
})
|
||||
const payload = buildErrorPayload(error, '服务内部错误')
|
||||
assert.equal(payload.msg, '服务内部错误')
|
||||
})
|
||||
|
||||
@@ -29,12 +29,16 @@ export function buildSuccessPayload(data: unknown, msg: string = 'ok') {
|
||||
|
||||
export function buildErrorPayload(error: unknown, fallbackMessage: string) {
|
||||
const classification = classifyRouteError(error)
|
||||
const message =
|
||||
classification.statusCode >= 500
|
||||
const errorMessage = error instanceof Error ? String(error.message || '').trim() : ''
|
||||
// 依赖方错误(如 affiliate_dash)即使映射为 5xx,也优先透出上游可读原因。
|
||||
const preferUpstreamMessage =
|
||||
errorMessage &&
|
||||
(classification.statusCode < 500 || classification.errorCode.startsWith('affiliate_dash'))
|
||||
const message = preferUpstreamMessage
|
||||
? errorMessage
|
||||
: classification.statusCode >= 500
|
||||
? fallbackMessage || '服务内部错误'
|
||||
: error instanceof Error
|
||||
? error.message
|
||||
: fallbackMessage
|
||||
: errorMessage || fallbackMessage
|
||||
|
||||
return {
|
||||
code: 1,
|
||||
|
||||
Reference in New Issue
Block a user