mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-23 13:03:50 +00:00
perf: openapi. error catch
This commit is contained in:
@@ -13,4 +13,4 @@ export const getOpenApiKeys = () => GET<UserOpenApiKey[]>('/openapi/getKeys');
|
||||
/**
|
||||
* delete api by id
|
||||
*/
|
||||
export const delOpenApiById = (id: string) => DELETE(`/openapi/delKet?id=${id}`);
|
||||
export const delOpenApiById = (id: string) => DELETE(`/openapi/delKey?id=${id}`);
|
||||
|
@@ -123,7 +123,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
formatRedisPrompt.unshift(prompts.shift()?.value || '');
|
||||
}
|
||||
|
||||
// textArr 筛选,最多 2800 tokens
|
||||
// 系统提示词筛选,最多 2800 tokens
|
||||
const systemPrompt = systemPromptFilter(formatRedisPrompt, 2800);
|
||||
|
||||
prompts.unshift({
|
||||
|
@@ -53,6 +53,12 @@ const ModelEditForm = ({
|
||||
})}
|
||||
></Input>
|
||||
</Flex>
|
||||
<Flex alignItems={'center'} mt={4}>
|
||||
<Box flex={'0 0 80px'} w={0}>
|
||||
modelId:
|
||||
</Box>
|
||||
<Box>{getValues('_id')}</Box>
|
||||
</Flex>
|
||||
</FormControl>
|
||||
<Flex alignItems={'center'} mt={4}>
|
||||
<Box flex={'0 0 80px'} w={0}>
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import {
|
||||
Card,
|
||||
Box,
|
||||
@@ -54,10 +55,21 @@ const OpenApi = () => {
|
||||
<>
|
||||
<Card px={6} py={4} position={'relative'}>
|
||||
<Box fontSize={'xl'} fontWeight={'bold'}>
|
||||
Open Api Key
|
||||
Open Api
|
||||
</Box>
|
||||
<Box fontSize={'sm'} mt={2}>
|
||||
请注意保管你的 key,不要泄露!
|
||||
Open Api 允许你将 Fast Gpt 的部分功能通过 api 的形式接入到自己的应用中。请注意保管你的 Api
|
||||
Key,不要泄露!
|
||||
</Box>
|
||||
<Box
|
||||
my={1}
|
||||
as="a"
|
||||
href="https://kjqvjse66l.feishu.cn/docx/DmLedTWtUoNGX8xui9ocdUEjnNh"
|
||||
color={'blue.800'}
|
||||
textDecoration={'underline'}
|
||||
target={'_blank'}
|
||||
>
|
||||
点击查看文档
|
||||
</Box>
|
||||
<TableContainer mt={2} position={'relative'}>
|
||||
<Table>
|
||||
@@ -93,16 +105,17 @@ const OpenApi = () => {
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
<Button
|
||||
mt={5}
|
||||
isLoading={isCreating}
|
||||
isDisabled={apiKeys.length >= 5}
|
||||
title={apiKeys.length >= 5 ? '最多五组 Api Key' : ''}
|
||||
onClick={() => onclickCreateApiKey()}
|
||||
>
|
||||
添加新的 Api Key
|
||||
</Button>
|
||||
</TableContainer>
|
||||
<Button
|
||||
maxW={'200px'}
|
||||
mt={5}
|
||||
isLoading={isCreating}
|
||||
isDisabled={apiKeys.length >= 5}
|
||||
title={apiKeys.length >= 5 ? '最多五组 Api Key' : ''}
|
||||
onClick={() => onclickCreateApiKey()}
|
||||
>
|
||||
添加新的 Api Key
|
||||
</Button>
|
||||
<Loading loading={isGetting || isDeleting} fixed={false} />
|
||||
</Card>
|
||||
<Modal isOpen={!!apiKey} onClose={() => setApiKey('')}>
|
||||
|
@@ -14,3 +14,30 @@ export const proxyError: Record<string, boolean> = {
|
||||
ECONNABORTED: true,
|
||||
ECONNRESET: true
|
||||
};
|
||||
|
||||
export enum ERROR_ENUM {
|
||||
unAuthorization = 'unAuthorization',
|
||||
insufficientQuota = 'insufficientQuota'
|
||||
}
|
||||
export const ERROR_RESPONSE: Record<
|
||||
any,
|
||||
{
|
||||
code: number;
|
||||
statusText: string;
|
||||
message: string;
|
||||
data?: any;
|
||||
}
|
||||
> = {
|
||||
[ERROR_ENUM.unAuthorization]: {
|
||||
code: 403,
|
||||
statusText: ERROR_ENUM.unAuthorization,
|
||||
message: '凭证错误',
|
||||
data: null
|
||||
},
|
||||
[ERROR_ENUM.insufficientQuota]: {
|
||||
code: 403,
|
||||
statusText: ERROR_ENUM.insufficientQuota,
|
||||
message: '账号余额不足',
|
||||
data: null
|
||||
}
|
||||
};
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { NextApiResponse } from 'next';
|
||||
import { openaiError, openaiError2, proxyError } from './errorCode';
|
||||
import { openaiError, openaiError2, proxyError, ERROR_RESPONSE } from './errorCode';
|
||||
|
||||
export interface ResponseType<T = any> {
|
||||
code: number;
|
||||
@@ -18,7 +18,14 @@ export const jsonRes = <T = any>(
|
||||
) => {
|
||||
const { code = 200, message = '', data = null, error } = props || {};
|
||||
|
||||
let msg = message;
|
||||
const errResponseKey = typeof error === 'string' ? error : error?.message;
|
||||
// Specified error
|
||||
if (ERROR_RESPONSE[errResponseKey]) {
|
||||
return res.json(ERROR_RESPONSE[errResponseKey]);
|
||||
}
|
||||
|
||||
// another error
|
||||
let msg = message || error?.message;
|
||||
if ((code < 200 || code >= 400) && !message) {
|
||||
msg = error?.message || '请求错误';
|
||||
if (typeof error === 'string') {
|
||||
@@ -40,7 +47,8 @@ export const jsonRes = <T = any>(
|
||||
|
||||
res.json({
|
||||
code,
|
||||
statusText: '',
|
||||
message: msg,
|
||||
data
|
||||
data: data || error || null
|
||||
});
|
||||
};
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import type { NextApiRequest } from 'next';
|
||||
import crypto from 'crypto';
|
||||
import jwt from 'jsonwebtoken';
|
||||
import tunnel from 'tunnel';
|
||||
import { ChatItemType } from '@/types/chat';
|
||||
import { encode } from 'gpt-token-utils';
|
||||
import { OpenApi, User } from '../mongo';
|
||||
import { formatPrice } from '@/utils/user';
|
||||
import { ERROR_ENUM } from '../errorCode';
|
||||
|
||||
/* 密码加密 */
|
||||
export const hashPassword = (psw: string) => {
|
||||
@@ -49,20 +49,20 @@ export const authOpenApiKey = async (req: NextApiRequest) => {
|
||||
const { apikey: apiKey } = req.headers;
|
||||
|
||||
if (!apiKey) {
|
||||
return Promise.reject('api key is empty');
|
||||
return Promise.reject(ERROR_ENUM.unAuthorization);
|
||||
}
|
||||
|
||||
try {
|
||||
const openApi = await OpenApi.findOne({ apiKey });
|
||||
if (!openApi) {
|
||||
return Promise.reject('api key is error');
|
||||
return Promise.reject(ERROR_ENUM.unAuthorization);
|
||||
}
|
||||
const userId = String(openApi.userId);
|
||||
|
||||
// 余额校验
|
||||
const user = await User.findById(userId);
|
||||
if (!user) {
|
||||
return Promise.reject('user is empty');
|
||||
return Promise.reject(ERROR_ENUM.unAuthorization);
|
||||
}
|
||||
if (formatPrice(user.balance) <= 0) {
|
||||
return Promise.reject('Insufficient account balance');
|
||||
|
Reference in New Issue
Block a user