Commit 5ac6575b by Archer Committed by GitHub

fix auth errors from Pro as user errors (#7334)

parent 7b5458ea
...@@ -23,6 +23,7 @@ type ResponseDataType = { ...@@ -23,6 +23,7 @@ type ResponseDataType = {
code: number; code: number;
message: string; message: string;
data: any; data: any;
errorType?: string;
}; };
/** /**
...@@ -49,6 +50,7 @@ function checkRes(data: ResponseDataType) { ...@@ -49,6 +50,7 @@ function checkRes(data: ResponseDataType) {
logger.error('Plus request response is empty', { data }); logger.error('Plus request response is empty', { data });
return Promise.reject('服务器异常'); return Promise.reject('服务器异常');
} else if (data?.code && (data.code < 200 || data.code >= 400)) { } else if (data?.code && (data.code < 200 || data.code >= 400)) {
if (data.errorType === 'UserError') return Promise.reject(new UserError(data.message));
return Promise.reject(data); return Promise.reject(data);
} }
return data.data; return data.data;
...@@ -66,6 +68,9 @@ function responseError(err: any) { ...@@ -66,6 +68,9 @@ function responseError(err: any) {
} }
if (err?.response?.data) { if (err?.response?.data) {
if (err.response.data.errorType === 'UserError') {
return Promise.reject(new UserError(err.response.data.message));
}
return Promise.reject(err?.response?.data); return Promise.reject(err?.response?.data);
} }
return Promise.reject(err); return Promise.reject(err);
......
...@@ -15,6 +15,7 @@ export interface ResponseType<T = any> { ...@@ -15,6 +15,7 @@ export interface ResponseType<T = any> {
code: number; code: number;
message: string; message: string;
data: T; data: T;
errorType?: string;
} }
export interface ProcessedError { export interface ProcessedError {
...@@ -173,7 +174,8 @@ export const jsonRes = <T = any>( ...@@ -173,7 +174,8 @@ export const jsonRes = <T = any>(
statusText: processedError.statusText, statusText: processedError.statusText,
message: message || processedError.message, message: message || processedError.message,
data: processedError.data !== undefined ? processedError.data : null, data: processedError.data !== undefined ? processedError.data : null,
zodError: processedError.zodError zodError: processedError.zodError,
errorType: error instanceof UserError ? 'UserError' : undefined
}); });
return; return;
......
...@@ -33,7 +33,7 @@ export const authOutLinkInit = async ({ ...@@ -33,7 +33,7 @@ export const authOutLinkInit = async ({
} }
}); });
if (data?.success !== true) { if (data?.success !== true) {
return Promise.reject(data?.message || data?.msg || OutLinkErrEnum.unAuthUser); return Promise.reject(new UserError(data?.message || data?.msg || OutLinkErrEnum.unAuthUser));
} }
const uid = data?.data?.uid; const uid = data?.data?.uid;
......
...@@ -106,4 +106,22 @@ describe('plusRequest', () => { ...@@ -106,4 +106,22 @@ describe('plusRequest', () => {
}) })
); );
}); });
it('Pro 返回 UserError 时转换为 FastGPT UserError', async () => {
vi.stubEnv('PRO_URL', 'https://pro.example.com');
vi.stubEnv('PRO_TOKEN', configuredProToken);
mockRequest.mockResolvedValueOnce({
data: {
code: 500,
message: 'API key has expired',
errorType: 'UserError'
}
});
const { POST } = await importPlusRequest();
await expect(POST('/support/openapi/authLimit', {})).rejects.toMatchObject({
name: 'UserError',
message: 'API key has expired'
});
});
}); });
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
"ai_settings": "AI Settings", "ai_settings": "AI Settings",
"all_apps": "All Applications", "all_apps": "All Applications",
"app.Version name": "Version Name", "app.Version name": "Version Name",
"app.error.publish_unExist_app": "Release failed, please check whether the tool call is normal", "app.error.publish_unExist_app": "Release failed. Please check that the tool configuration is correct",
"app.modules.has new version": "New Version Available", "app.modules.has new version": "New Version Available",
"app.version_current": "Current Version", "app.version_current": "Current Version",
"app.version_initial": "Initial Version", "app.version_initial": "Initial Version",
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
"ai_settings": "AI 配置", "ai_settings": "AI 配置",
"all_apps": "全部应用", "all_apps": "全部应用",
"app.Version name": "版本名称", "app.Version name": "版本名称",
"app.error.publish_unExist_app": "发布失败,请检查工具调用是否正常", "app.error.publish_unExist_app": "发布失败,请检查工具配置是否正确",
"app.modules.has new version": "新版本", "app.modules.has new version": "新版本",
"app.version_current": "当前版本", "app.version_current": "当前版本",
"app.version_initial": "初始版本", "app.version_initial": "初始版本",
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
"ai_settings": "AI 設定", "ai_settings": "AI 設定",
"all_apps": "所有應用程式", "all_apps": "所有應用程式",
"app.Version name": "版本名稱", "app.Version name": "版本名稱",
"app.error.publish_unExist_app": "發布失敗,請檢查工具呼叫是否正常", "app.error.publish_unExist_app": "發布失敗,請檢查工具設定是否正確",
"app.modules.has new version": "新版本", "app.modules.has new version": "新版本",
"app.version_current": "目前版本", "app.version_current": "目前版本",
"app.version_initial": "初始版本", "app.version_initial": "初始版本",
......
...@@ -37,6 +37,7 @@ import { getDisplayHistoryTitle } from '@/web/core/chat/context/historyTitleUtil ...@@ -37,6 +37,7 @@ import { getDisplayHistoryTitle } from '@/web/core/chat/context/historyTitleUtil
import { getAppChatSourceKey } from '@/web/core/chat/utils'; import { getAppChatSourceKey } from '@/web/core/chat/utils';
import { useAppChatGenerateStatusSync } from './useAppChatGenerateStatusSync'; import { useAppChatGenerateStatusSync } from './useAppChatGenerateStatusSync';
import { postMarkChatRead } from '@/web/core/chat/history/api'; import { postMarkChatRead } from '@/web/core/chat/history/api';
import { UserError } from '@fastgpt/global/common/error/utils';
const CustomPluginRunBox = dynamic(() => import('@/pageComponents/chat/CustomPluginRunBox')); const CustomPluginRunBox = dynamic(() => import('@/pageComponents/chat/CustomPluginRunBox'));
...@@ -147,7 +148,7 @@ const AppChatWindow = () => { ...@@ -147,7 +148,7 @@ const AppChatWindow = () => {
generatingMessage generatingMessage
}: StartChatFnProps) => { }: StartChatFnProps) => {
if (!appId) { if (!appId) {
return Promise.reject('appId is empty'); return Promise.reject(new UserError('appId is empty'));
} }
const histories = messages.slice(-1); const histories = messages.slice(-1);
......
...@@ -57,6 +57,7 @@ import { getAppChatSourceKey } from '@/web/core/chat/utils'; ...@@ -57,6 +57,7 @@ import { getAppChatSourceKey } from '@/web/core/chat/utils';
import { useAppChatGenerateStatusSync } from './useAppChatGenerateStatusSync'; import { useAppChatGenerateStatusSync } from './useAppChatGenerateStatusSync';
import { postMarkChatRead } from '@/web/core/chat/history/api'; import { postMarkChatRead } from '@/web/core/chat/history/api';
import { homeChatFileSelectConfig } from '@fastgpt/global/core/chat/setting/constants'; import { homeChatFileSelectConfig } from '@fastgpt/global/core/chat/setting/constants';
import { UserError } from '@fastgpt/global/common/error/utils';
const defaultFileSelectConfig: AppFileSelectConfigType = { const defaultFileSelectConfig: AppFileSelectConfigType = {
...homeChatFileSelectConfig, ...homeChatFileSelectConfig,
...@@ -244,14 +245,14 @@ const HomeChatWindow = () => { ...@@ -244,14 +245,14 @@ const HomeChatWindow = () => {
generatingMessage generatingMessage
}: StartChatFnProps) => { }: StartChatFnProps) => {
if (!appId) { if (!appId) {
return Promise.reject('appId is empty'); return Promise.reject(new UserError('appId is empty'));
} }
const histories = messages.slice(-1); const histories = messages.slice(-1);
// Home chat uses the selected model and tools. Quick apps enter the normal app chat pane. // Home chat uses the selected model and tools. Quick apps enter the normal app chat pane.
if (!selectedModel) { if (!selectedModel) {
return Promise.reject('No model selected'); return Promise.reject(new UserError('No model selected'));
} }
const tools: FlowNodeTemplateType[] = await Promise.all( const tools: FlowNodeTemplateType[] = await Promise.all(
......
...@@ -13,6 +13,7 @@ import { authCert } from '@fastgpt/service/support/permission/auth/common'; ...@@ -13,6 +13,7 @@ import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { MongoUser } from '@fastgpt/service/support/user/schema'; import { MongoUser } from '@fastgpt/service/support/user/schema';
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema'; import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
import { ChatSourceTypeEnum } from '@fastgpt/global/core/chat/constants'; import { ChatSourceTypeEnum } from '@fastgpt/global/core/chat/constants';
import { UserError } from '@fastgpt/global/common/error/utils';
/** /**
* 解析 Chat Completions 请求最终应归属的团队成员。 * 解析 Chat Completions 请求最终应归属的团队成员。
...@@ -141,7 +142,7 @@ export const authChatCompletionHeaderRequest = async ({ ...@@ -141,7 +142,7 @@ export const authChatCompletionHeaderRequest = async ({
authType === AuthUserTypeEnum.apikey ? appId || parsedAppId || legacyAppId : appId; authType === AuthUserTypeEnum.apikey ? appId || parsedAppId || legacyAppId : appId;
if (!currentAppId) { if (!currentAppId) {
return Promise.reject('appId is empty'); return Promise.reject(new UserError('appId is empty'));
} }
const { app, permission } = await (async () => { const { app, permission } = await (async () => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment