Commit 5ac6575b by Archer Committed by GitHub

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

parent 7b5458ea
......@@ -23,6 +23,7 @@ type ResponseDataType = {
code: number;
message: string;
data: any;
errorType?: string;
};
/**
......@@ -49,6 +50,7 @@ function checkRes(data: ResponseDataType) {
logger.error('Plus request response is empty', { data });
return Promise.reject('服务器异常');
} 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 data.data;
......@@ -66,6 +68,9 @@ function responseError(err: any) {
}
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);
......
......@@ -15,6 +15,7 @@ export interface ResponseType<T = any> {
code: number;
message: string;
data: T;
errorType?: string;
}
export interface ProcessedError {
......@@ -173,7 +174,8 @@ export const jsonRes = <T = any>(
statusText: processedError.statusText,
message: message || processedError.message,
data: processedError.data !== undefined ? processedError.data : null,
zodError: processedError.zodError
zodError: processedError.zodError,
errorType: error instanceof UserError ? 'UserError' : undefined
});
return;
......
......@@ -33,7 +33,7 @@ export const authOutLinkInit = async ({
}
});
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;
......
......@@ -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 @@
"ai_settings": "AI Settings",
"all_apps": "All Applications",
"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.version_current": "Current Version",
"app.version_initial": "Initial Version",
......
......@@ -42,7 +42,7 @@
"ai_settings": "AI 配置",
"all_apps": "全部应用",
"app.Version name": "版本名称",
"app.error.publish_unExist_app": "发布失败,请检查工具调用是否正常",
"app.error.publish_unExist_app": "发布失败,请检查工具配置是否正确",
"app.modules.has new version": "新版本",
"app.version_current": "当前版本",
"app.version_initial": "初始版本",
......
......@@ -40,7 +40,7 @@
"ai_settings": "AI 設定",
"all_apps": "所有應用程式",
"app.Version name": "版本名稱",
"app.error.publish_unExist_app": "發布失敗,請檢查工具呼叫是否正常",
"app.error.publish_unExist_app": "發布失敗,請檢查工具設定是否正確",
"app.modules.has new version": "新版本",
"app.version_current": "目前版本",
"app.version_initial": "初始版本",
......
......@@ -37,6 +37,7 @@ import { getDisplayHistoryTitle } from '@/web/core/chat/context/historyTitleUtil
import { getAppChatSourceKey } from '@/web/core/chat/utils';
import { useAppChatGenerateStatusSync } from './useAppChatGenerateStatusSync';
import { postMarkChatRead } from '@/web/core/chat/history/api';
import { UserError } from '@fastgpt/global/common/error/utils';
const CustomPluginRunBox = dynamic(() => import('@/pageComponents/chat/CustomPluginRunBox'));
......@@ -147,7 +148,7 @@ const AppChatWindow = () => {
generatingMessage
}: StartChatFnProps) => {
if (!appId) {
return Promise.reject('appId is empty');
return Promise.reject(new UserError('appId is empty'));
}
const histories = messages.slice(-1);
......
......@@ -57,6 +57,7 @@ import { getAppChatSourceKey } from '@/web/core/chat/utils';
import { useAppChatGenerateStatusSync } from './useAppChatGenerateStatusSync';
import { postMarkChatRead } from '@/web/core/chat/history/api';
import { homeChatFileSelectConfig } from '@fastgpt/global/core/chat/setting/constants';
import { UserError } from '@fastgpt/global/common/error/utils';
const defaultFileSelectConfig: AppFileSelectConfigType = {
...homeChatFileSelectConfig,
......@@ -244,14 +245,14 @@ const HomeChatWindow = () => {
generatingMessage
}: StartChatFnProps) => {
if (!appId) {
return Promise.reject('appId is empty');
return Promise.reject(new UserError('appId is empty'));
}
const histories = messages.slice(-1);
// Home chat uses the selected model and tools. Quick apps enter the normal app chat pane.
if (!selectedModel) {
return Promise.reject('No model selected');
return Promise.reject(new UserError('No model selected'));
}
const tools: FlowNodeTemplateType[] = await Promise.all(
......
......@@ -13,6 +13,7 @@ import { authCert } from '@fastgpt/service/support/permission/auth/common';
import { MongoUser } from '@fastgpt/service/support/user/schema';
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
import { ChatSourceTypeEnum } from '@fastgpt/global/core/chat/constants';
import { UserError } from '@fastgpt/global/common/error/utils';
/**
* 解析 Chat Completions 请求最终应归属的团队成员。
......@@ -141,7 +142,7 @@ export const authChatCompletionHeaderRequest = async ({
authType === AuthUserTypeEnum.apikey ? appId || parsedAppId || legacyAppId : appId;
if (!currentAppId) {
return Promise.reject('appId is empty');
return Promise.reject(new UserError('appId is empty'));
}
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