fix(account): 同步上游模型失败时显示后端返回的错误原因

- apiClient 拒绝的是普通对象而非 Error,原写法 instanceof Error 恒为假,
  错误提示被替换成通用文案"同步上游模型失败:同步上游模型失败"
- 白名单选择器与 Antigravity 同步按钮改用 extractApiErrorMessage 取消息
This commit is contained in:
feeeei
2026-10-10 23:37:48 +08:00
parent 6f9b02f12c
commit c9e4b267b6
3 changed files with 24 additions and 3 deletions
@@ -4771,7 +4771,7 @@ const syncAntigravityUpstreamModels = async () => {
appStore.showWarning(t('admin.accounts.syncUpstreamModelsMetadataPartial'))
}
} catch (error) {
const message = error instanceof Error ? error.message : t('admin.accounts.syncUpstreamModelsFailed')
const message = extractApiErrorMessage(error, t('admin.accounts.syncUpstreamModelsFailed'))
appStore.showError(t('admin.accounts.syncUpstreamModelsError', { message }))
} finally {
isSyncingAntigravityUpstream.value = false
@@ -155,6 +155,7 @@ import ModelIcon from '@/components/common/ModelIcon.vue'
import Icon from '@/components/icons/Icon.vue'
import { allModels, getModelsByPlatform } from '@/composables/useModelWhitelist'
import { supportsUpstreamModelSync } from '@/constants/platformCatalog'
import { extractApiErrorMessage } from '@/utils/apiError'
const { t } = useI18n()
@@ -343,7 +344,7 @@ const syncUpstreamModels = async () => {
appStore.showWarning(t('admin.accounts.syncUpstreamModelsMetadataPartial'))
}
} catch (error) {
const message = error instanceof Error ? error.message : t('admin.accounts.syncUpstreamModelsFailed')
const message = extractApiErrorMessage(error, t('admin.accounts.syncUpstreamModelsFailed'))
appStore.showError(t('admin.accounts.syncUpstreamModelsError', { message }))
} finally {
isSyncingUpstream.value = false
@@ -29,7 +29,7 @@ vi.mock('vue-i18n', async () => {
return {
...actual,
useI18n: () => ({
t: (key: string, params?: Record<string, string>) => key === 'common.copy' ? '复制' : key === 'admin.accounts.modelMappingConflict' ? `Model mapping conflict: ${params?.from} → ${params?.to}` : key
t: (key: string, params?: Record<string, string>) => key === 'common.copy' ? '复制' : key === 'admin.accounts.modelMappingConflict' ? `Model mapping conflict: ${params?.from} → ${params?.to}` : key === 'admin.accounts.syncUpstreamModelsError' ? `${key}: ${params?.message}` : key
})
}
})
@@ -244,6 +244,26 @@ describe('ModelWhitelistSelector', () => {
expect(showSuccess).not.toHaveBeenCalled()
})
it('shows the backend message when upstream sync is rejected', async () => {
syncUpstreamModels.mockRejectedValue({
status: 400,
code: 'BAD_REQUEST',
message: 'Vertex API key accounts do not support upstream model listing'
})
const wrapper = mountSelector({ platform: 'gemini', accountId: 174 })
const syncButton = wrapper
.findAll('button')
.find(button => button.text() === 'admin.accounts.syncUpstreamModels')
expect(syncButton).toBeDefined()
await syncButton!.trigger('click')
await flushPromises()
expect(showError).toHaveBeenCalledWith(
'admin.accounts.syncUpstreamModelsError: Vertex API key accounts do not support upstream model listing'
)
})
it('shows success and a partial warning when some capabilities were saved', async () => {
syncUpstreamModels.mockResolvedValue({
models: ['gpt-6-astra', 'gpt-image-2'],