Skip to content

Commit

Permalink
improv: improve error dialog
Browse files Browse the repository at this point in the history
  • Loading branch information
moeakwak committed Jun 23, 2023
1 parent 72ad066 commit 9d5f1b1
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 52 deletions.
19 changes: 14 additions & 5 deletions backend/api/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def __init__(self, reason: Any = None, message: str = "", code: int = -1) -> Non
self.code = code # 错误码:负数为自定义错误;正数为 http 错误码

def __str__(self):
return f"{self.__class__.__name__}: {self.code} {self.message}"
return f"{self.__class__.__name__}: [{self.code}] {self.reason} {self.message}"


class AuthorityDenyException(SelfDefinedException):
Expand Down Expand Up @@ -51,7 +51,16 @@ def __init__(self, message: str = ""):
super().__init__(reason="errors.config", message=message)


class OpenaiWebException(SelfDefinedException):
def __init__(self, message: str = "", status_code: int = -1):
super().__init__(reason="errors.openaiWeb", message=message)
self.status_code = status_code
class OpenaiException(SelfDefinedException):
def __init__(self, reason: str, message: str = "", code: int = -1):
super().__init__(reason=reason, message=message, code=code)


class OpenaiWebException(OpenaiException):
def __init__(self, message: str = "", code: int = -1):
super().__init__(reason="errors.openaiWeb", message=message, code=code)


class OpenaiApiException(OpenaiException):
def __init__(self, message: str = "", code: int = -1):
super().__init__(reason="errors.openaiWeb", message=message, code=code)
34 changes: 17 additions & 17 deletions backend/api/routers/chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from api.conf import Config
from api.database import get_async_session_context
from api.enums import OpenaiWebChatStatus, ChatSourceTypes, OpenaiWebChatModels, OpenaiApiChatModels
from api.exceptions import InternalException, InvalidParamsException
from api.exceptions import InternalException, InvalidParamsException, OpenaiException
from api.models.db import OpenaiWebConversation, User, BaseConversation
from api.models.doc import OpenaiWebChatMessage, OpenaiApiChatMessage, OpenaiWebConversationHistoryDocument, \
OpenaiApiConversationHistoryDocument, OpenaiApiChatMessageTextContent, AskLogDocument, OpenaiWebAskLogMeta, \
Expand All @@ -27,7 +27,7 @@
from api.schemas import OpenaiWebConversationSchema, AskRequest, AskResponse, AskResponseType, UserReadAdmin, \
BaseConversationSchema
from api.schemas.openai_schemas import OpenaiChatPlugin, OpenaiChatPluginUserSettings
from api.sources import OpenaiWebChatManager, convert_revchatgpt_message, OpenaiApiChatManager, OpenAIChatException
from api.sources import OpenaiWebChatManager, convert_revchatgpt_message, OpenaiApiChatManager, OpenaiApiException
from api.users import websocket_auth, current_active_user, current_super_user
from utils.logger import get_logger

Expand Down Expand Up @@ -326,24 +326,25 @@ async def reply(response: AskResponse):
))
websocket_code = 1001
websocket_reason = "errors.timout"
except revChatGPTError as e:
except OpenaiException as e:
logger.error(str(e))
content = check_message(f"{e.source} {e.code}: {e.message}")
error_detail_map = {
401: "errors.openai.401",
403: "errors.openai.403",
404: "errors.openai.404",
429: "errors.openai.429",
}
if e.code in error_detail_map:
tip = error_detail_map[e.code]
else:
tip = "errors.openai.unknown"
await reply(AskResponse(
type=AskResponseType.error,
tip="errors.chatgptResponseError",
error_detail=content
tip=tip,
error_detail=check_message(str(e))
))
websocket_code = 1001
websocket_reason = "errors.chatgptResponseError"
except OpenAIChatException as e:
logger.error(str(e))
content = check_message(str(e))
await reply(AskResponse(
type=AskResponseType.error,
tip="errors.openaiResponseError",
error_detail=str(e)
))
websocket_reason = "errors.openaiResponseUnknownError"
except HTTPError as e:
logger.error(str(e))
content = check_message(str(e))
Expand All @@ -356,11 +357,10 @@ async def reply(response: AskResponse):
websocket_reason = "errors.httpError"
except Exception as e:
logger.error(str(e))
content = check_message(str(e))
await reply(AskResponse(
type=AskResponseType.error,
tip="errors.unknownError",
error_detail=content
error_detail=check_message(str(e))
))
websocket_code = 1011
websocket_reason = "errors.unknownError"
Expand Down
14 changes: 2 additions & 12 deletions backend/api/sources/openai_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from api.conf import Config, Credentials
from api.enums import OpenaiApiChatModels, ChatSourceTypes
from api.exceptions import OpenaiApiException
from api.models.doc import OpenaiApiChatMessage, OpenaiApiConversationHistoryDocument, OpenaiApiChatMessageMetadata, \
OpenaiApiChatMessageTextContent
from api.schemas.openai_schemas import OpenaiChatResponse
Expand All @@ -22,24 +23,13 @@
MAX_CONTEXT_MESSAGE_COUNT = 1000


class OpenAIChatException(Exception):
def __init__(self, source: str, message: str, code: int = None):
self.source = source
self.message = message
self.code = code

def __str__(self):
return f"{self.source} {self.code} error: {self.message}"


async def _check_response(response: httpx.Response) -> None:
# 改成自带的错误处理
try:
response.raise_for_status()
except httpx.HTTPStatusError as ex:
await response.aread()
error = OpenAIChatException(
source="OpenAI",
error = OpenaiApiException(
message=response.text,
code=response.status_code,
)
Expand Down
2 changes: 1 addition & 1 deletion backend/api/sources/openai_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ async def _check_response(response: httpx.Response) -> None:
await response.aread()
error = OpenaiWebException(
message=response.text,
status_code=response.status_code,
code=response.status_code,
)
raise error from ex

Expand Down
37 changes: 31 additions & 6 deletions frontend/src/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,6 @@
"quoteContent": "Quote Content",
"click": "Click",
"error": "Error",
"browsingActions": "Browsing History",
"browsingHistory": "Browsing History",
"shouldRenderMarkdown": "Whether Render Content As Markdown",
"showRawMessage": "Show raw messages",
Expand All @@ -155,7 +154,19 @@
"minutes": "minute",
"times": "Second-rate",
"scrolling_down": "Scrolling down",
"detail": "details"
"detail": "details",
"openaiSettings": "OpenAI Settings",
"all": "all",
"disable": "disabled",
"enable": "enable",
"enabled": "activated",
"install": "Install",
"installed": "Installed",
"most_popular": "most popular",
"newly_added": "Add",
"noPluginsAvailable": "Failed to get the plugin list, please check whether the item \"openai_web.is_plus_account\" is set to true",
"pluginSettings": "OpenAI Web Plugin Settings",
"uninstall": "uninstall"
},
"errors": {
"403": "403 error: access denied",
Expand Down Expand Up @@ -188,7 +199,15 @@
"invalidParams": "Invalid Params",
"noAvailableTotalAskCount": "The total number of conversations that are not available for this type of conversation",
"userChatTypeExpired": "The validity period of this conversation type has expired, please contact the administrator to increase the duration",
"userNotAllowToAskAtThisTime": "Questions are not allowed in the current time period"
"userNotAllowToAskAtThisTime": "Questions are not allowed in the current time period",
"openai": {
"401": "OpenAI authorization failed (401 error), please contact the administrator",
"403": "OpenAI authorization failed (403 error), please contact the administrator",
"404": "The OpenAI interface does not exist (404 error), please contact the administrator",
"429": "The OpenAI interface request is too frequent (429 error), it may be that the model usage limit has been exceeded, please try again later",
"unkown": "OpenAI unknown error, please contact the administrator"
},
"unknown": "unknown mistake"
},
"tips": {
"loginExpired": "Login expired. Do you want to go to the login page?",
Expand Down Expand Up @@ -240,7 +259,10 @@
"pleaseCheckInput": "Please check the input",
"registerSuccess": "registration success",
"seperate_settings": "The following will set options for using revChatGPT and API respectively",
"updateSuccess": "update completed"
"updateSuccess": "update completed",
"disablePluginSuccess": "Disable plugin successfully",
"enablePluginSuccess": "Enable plugin successfully",
"installSuccess": "Successful installation"
},
"labels": {
"nickname": "Nickname",
Expand Down Expand Up @@ -283,7 +305,9 @@
"type": "type",
"username": "username",
"valid_until": "validity period",
"source": "source"
"source": "source",
"gpt4_count_in_3_hours": "GPT-4 dosage / 3h",
"plugins": "plug-in"
},
"models": {
"gpt_3_5": "GPT-3.5",
Expand All @@ -303,6 +327,7 @@
},
"desc": {
"daily_available_time_slots": "It is only allowed to be used during these time periods of the day, if it is empty, it means unlimited.",
"rate_limits": "Define the maximum number of conversations a user can initiate within a certain time interval, and the priority is calculated from small to large time intervals."
"rate_limits": "Define the maximum number of conversations a user can initiate within a certain time interval, and the priority is calculated from small to large time intervals.",
"openai_web_installed_plugins": "Note: Only the plugins enabled here can be selected when using GPT-4 Plugin!"
}
}
13 changes: 11 additions & 2 deletions frontend/src/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@
"enable": "启用",
"enabled": "已启用",
"scrolling_down": "向下浏览",
"detail": "详情"
"detail": "详情",
"openaiSettings": "OpenAI 设置"
},
"errors": {
"403": "403 错误:无访问权限",
Expand Down Expand Up @@ -198,7 +199,15 @@
"internal": "内部错误",
"noAvailableTotalAskCount": "该类型对话方式无可用总对话次数",
"userChatTypeExpired": "该对话类型有效期已到期,请联系管理员增加时长",
"userNotAllowToAskAtThisTime": "当前时间段不允许提问"
"userNotAllowToAskAtThisTime": "当前时间段不允许提问",
"openai": {
"401": "OpenAI 授权失败 (401 错误),请联系管理员处理",
"403": "OpenAI 授权失败 (403 错误),请联系管理员处理",
"404": "OpenAI 接口不存在 (404 错误),请联系管理员处理",
"429": "OpenAI 接口请求过于频繁 (429 错误),可能是超过模型使用限制,请稍后再试",
"unkown": "OpenAI 未知错误,请联系管理员处理"
},
"unknown": "未知错误"
},
"tips": {
"loginExpired": "登录已过期。是否跳转到登录页面?",
Expand Down
23 changes: 14 additions & 9 deletions frontend/src/views/conversation/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ const sendMsg = async () => {
currentRecvMessages.value = [buildTemporaryMessage('assistant', '...', currentSendMessage.value.id, currentConversation.value!.current_model!)];
const wsUrl = getAskWebsocketApiUrl();
let hasError = false;
let wsErrorMessage: string | null = null;
let wsErrorMessage: AskResponse | null = null;
console.log('Connecting to', wsUrl, askRequest);
const webSocket = new WebSocket(wsUrl);
Expand Down Expand Up @@ -321,9 +321,7 @@ const sendMsg = async () => {
} else if (response.type === 'error') {
hasError = true;
console.error('websocket received error message', response);
if (response.error_detail) {
wsErrorMessage = response.error_detail;
}
wsErrorMessage = response;
}
if (autoScrolling.value) scrollToBottom();
};
Expand All @@ -332,7 +330,7 @@ const sendMsg = async () => {
aborter = null;
canAbort.value = false;
console.log('WebSocket connection is closed', event, isAborted.value);
if ((isAborted.value || event.code === 1000) && !hasError) {
if (!hasError && (event.code == 1000 || isAborted.value)) {
// 正常关闭
if (hasGotReply) {
const allNewMessages = [currentSendMessage.value] as BaseChatMessage[];
Expand Down Expand Up @@ -367,12 +365,19 @@ const sendMsg = async () => {
console.log('done', allNewMessages, currentConversationId.value);
}
} else {
let content = '';
if (wsErrorMessage != null) {
if (wsErrorMessage.tip) {
content = t(wsErrorMessage.tip);
} else {
content = wsErrorMessage.error_detail || t('errors.unknown');
}
} else {
content = `WebSocket ${event.code}: ${t(event.reason || 'errors.unknown')}`;
}
Dialog.error({
title: t('errors.askError'),
content:
wsErrorMessage != null
? `${t(event.reason)}: ${wsErrorMessage}`
: `${t(event.reason)}`,
content,
positiveText: t('commons.withdrawMessage'),
negativeText: t('commons.cancel'),
onPositiveClick: () => {
Expand Down

0 comments on commit 9d5f1b1

Please sign in to comment.