Fix chat experience (#211)
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"type": "patch",
|
||||
"comment": "fix chat experience for error",
|
||||
"packageName": "@acedatacloud/nexior",
|
||||
"email": "cqc@cuiqingcai.com",
|
||||
"dependentChangeType": "patch"
|
||||
}
|
||||
@@ -36,6 +36,7 @@ html.dark,
|
||||
word-wrap: break-word;
|
||||
border-radius: 1rem;
|
||||
border: none;
|
||||
--el-card-padding: 15px;
|
||||
}
|
||||
|
||||
.el-breadcrumb__inner a,
|
||||
|
||||
@@ -171,9 +171,13 @@ export default defineComponent({
|
||||
return this.$store.state.chat.modelGroup;
|
||||
},
|
||||
errorText() {
|
||||
console.debug('error', this.message.error);
|
||||
if (!this.message.error || !this.message.error?.code) {
|
||||
return undefined;
|
||||
}
|
||||
if (this.message.error?.message) {
|
||||
return this.message.error.message;
|
||||
}
|
||||
switch (this.message.error?.code) {
|
||||
case ERROR_CODE_USED_UP:
|
||||
return this.$t('chat.message.errorUsedUp');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="relative inline-block text-left">
|
||||
<div class="center">
|
||||
<div @click="toggleMenu">
|
||||
<user-avatar class="cursor-pointer" />
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export const ERROR_STATUS_BAD_REQUEST = 400;
|
||||
export const ERROR_STATUS_FORBIDDEN = 403;
|
||||
export const ERROR_STATUS_TOO_MANY_REQUESTS = 429;
|
||||
export const ERROR_STATUS_NOT_FOUND = 404;
|
||||
export const ERROR_STATUS_API_ERROR = 500;
|
||||
export const ERROR_STATUS_TIMEOUT = 504;
|
||||
export const ERROR_STATUS_BUSY = 500;
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from './errorCode';
|
||||
export * from './errorStatus';
|
||||
export * from './endpoint';
|
||||
export * from './action';
|
||||
export * from './chat';
|
||||
|
||||
@@ -64,7 +64,7 @@ export default defineComponent({
|
||||
|
||||
.chat {
|
||||
height: 100%;
|
||||
padding: 15px;
|
||||
padding: 45px 0 0 15px;
|
||||
flex: 1;
|
||||
width: calc(100% - 250px);
|
||||
height: 100%;
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
import {
|
||||
ERROR_CODE_API_ERROR,
|
||||
ERROR_CODE_BAD_REQUEST,
|
||||
ERROR_CODE_BUSY,
|
||||
ERROR_CODE_FORBIDDEN,
|
||||
ERROR_CODE_TIMEOUT,
|
||||
ERROR_CODE_TOO_MANY_REQUESTS,
|
||||
ERROR_STATUS_API_ERROR,
|
||||
ERROR_STATUS_BAD_REQUEST,
|
||||
ERROR_STATUS_BUSY,
|
||||
ERROR_STATUS_FORBIDDEN,
|
||||
ERROR_STATUS_TIMEOUT,
|
||||
ERROR_STATUS_TOO_MANY_REQUESTS
|
||||
} from '@/constants';
|
||||
|
||||
export class BaseError extends Error {
|
||||
public status: number;
|
||||
public code: string;
|
||||
public detail: string;
|
||||
public extraData?: Record<string, any>;
|
||||
|
||||
constructor(status: number, code: string, detail: string, extraData?: Record<string, any>) {
|
||||
super();
|
||||
this.status = status;
|
||||
this.code = code;
|
||||
this.detail = detail;
|
||||
this.extraData = extraData;
|
||||
}
|
||||
|
||||
get message(): string {
|
||||
return `${this.code} - ${this.detail}`;
|
||||
}
|
||||
}
|
||||
|
||||
export class BadRequestError extends BaseError {
|
||||
constructor(detail: string, extraData?: Record<string, any>) {
|
||||
super(ERROR_STATUS_BAD_REQUEST, ERROR_CODE_BAD_REQUEST, detail, extraData);
|
||||
}
|
||||
}
|
||||
|
||||
export class ApiError extends BaseError {
|
||||
constructor(detail: string, extraData?: Record<string, any>) {
|
||||
super(ERROR_STATUS_API_ERROR, ERROR_CODE_API_ERROR, detail, extraData);
|
||||
}
|
||||
}
|
||||
|
||||
export class BusyError extends BaseError {
|
||||
constructor(detail: string, extraData?: Record<string, any>) {
|
||||
super(ERROR_STATUS_BUSY, ERROR_CODE_BUSY, detail, extraData);
|
||||
}
|
||||
}
|
||||
|
||||
export class ForbiddenError extends BaseError {
|
||||
constructor(detail: string, extraData?: Record<string, any>) {
|
||||
super(ERROR_STATUS_FORBIDDEN, ERROR_CODE_FORBIDDEN, detail, extraData);
|
||||
}
|
||||
}
|
||||
|
||||
export class TimeoutError extends BaseError {
|
||||
constructor(detail: string, extraData?: Record<string, any>) {
|
||||
super(ERROR_STATUS_TIMEOUT, ERROR_CODE_TIMEOUT, detail, extraData);
|
||||
}
|
||||
}
|
||||
|
||||
export class TooManyRequestsError extends BaseError {
|
||||
constructor(detail: string, extraData?: Record<string, any>) {
|
||||
super(ERROR_STATUS_TOO_MANY_REQUESTS, ERROR_CODE_TOO_MANY_REQUESTS, detail, extraData);
|
||||
}
|
||||
}
|
||||
@@ -21,3 +21,4 @@ export * from './headshots';
|
||||
export * from './suno';
|
||||
export * from './site';
|
||||
export * from './exchange';
|
||||
export * from './error';
|
||||
|
||||
+16
-2
@@ -1,5 +1,7 @@
|
||||
import axios, { AxiosResponse } from 'axios';
|
||||
import {
|
||||
ApiError,
|
||||
BaseError,
|
||||
IChatConversation,
|
||||
IChatConversationAction,
|
||||
IChatConversationOptions,
|
||||
@@ -7,7 +9,7 @@ import {
|
||||
IChatConversationResponse,
|
||||
IChatConversationsResponse
|
||||
} from '@/models';
|
||||
import { BASE_URL_API } from '@/constants';
|
||||
import { BASE_URL_API, ERROR_CODE_API_ERROR } from '@/constants';
|
||||
|
||||
class ChatOperator {
|
||||
async chatConversation(
|
||||
@@ -27,7 +29,19 @@ class ChatOperator {
|
||||
body: JSON.stringify(data)
|
||||
});
|
||||
|
||||
if (!response.body) throw new Error('ReadableStream not supported.');
|
||||
// check response status
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
const status = response.status;
|
||||
const errorJson = errorText ? JSON.parse(errorText) : {};
|
||||
const errorMessage = errorJson?.error?.message || 'An error occurred';
|
||||
const errorCode = errorJson?.error?.code || ERROR_CODE_API_ERROR;
|
||||
console.error('Error message:', errorMessage, 'Error code:', errorCode);
|
||||
reject(new BaseError(status, errorCode, errorMessage));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response.body) throw new ApiError('ReadableStream not supported.');
|
||||
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
@restart="onRestart"
|
||||
/>
|
||||
</div>
|
||||
<div class="composer">
|
||||
<div class="starter">
|
||||
<composer
|
||||
v-model:question="question"
|
||||
:disabled="answering"
|
||||
@@ -38,7 +38,7 @@ import axios from 'axios';
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import Message from '@/components/chat/Message.vue';
|
||||
import { CHAT_MODEL_GROUPS, CHAT_MODELS, ROLE_ASSISTANT, ROLE_USER } from '@/constants';
|
||||
import { IChatMessageState, IChatConversationResponse, IChatConversation, IChatMessage } from '@/models';
|
||||
import { IChatMessageState, IChatConversationResponse, IChatConversation, IChatMessage, BaseError } from '@/models';
|
||||
import Composer from '@/components/chat/Composer.vue';
|
||||
import ModelSelector from '@/components/chat/ModelSelector.vue';
|
||||
import { ERROR_CODE_CANCELED, ERROR_CODE_NOT_APPLIED, ERROR_CODE_UNKNOWN } from '@/constants/errorCode';
|
||||
@@ -447,27 +447,23 @@ export default defineComponent({
|
||||
});
|
||||
},
|
||||
async handleRequestError(error: any) {
|
||||
console.error('error happened', error);
|
||||
if (this.messages && this.messages.length > 0) {
|
||||
this.messages[this.messages.length - 1].state = IChatMessageState.FAILED;
|
||||
}
|
||||
if (error.name === 'AbortError') {
|
||||
console.error('aborted');
|
||||
return;
|
||||
}
|
||||
console.error(error);
|
||||
if (axios.isCancel(error)) {
|
||||
} else if (error instanceof BaseError) {
|
||||
console.debug('BaseError', error);
|
||||
this.messages[this.messages.length - 1].error = {
|
||||
code: error.code,
|
||||
message: error.detail
|
||||
};
|
||||
} else if (axios.isCancel(error)) {
|
||||
this.messages[this.messages.length - 1].error = {
|
||||
code: ERROR_CODE_CANCELED
|
||||
};
|
||||
} else if (error?.response?.data) {
|
||||
let data = error?.response?.data;
|
||||
if (isJSONString(data)) {
|
||||
data = JSON.parse(data);
|
||||
}
|
||||
console.debug('error', data);
|
||||
if (this.messages && this.messages.length > 0) {
|
||||
this.messages[this.messages.length - 1].error = data.error;
|
||||
}
|
||||
} else {
|
||||
if (this.messages && this.messages.length > 0) {
|
||||
this.messages[this.messages.length - 1].error = {
|
||||
@@ -526,7 +522,7 @@ export default defineComponent({
|
||||
}
|
||||
&.empty {
|
||||
position: relative;
|
||||
.composer {
|
||||
.starter {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
top: 50%;
|
||||
@@ -543,7 +539,7 @@ export default defineComponent({
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
}
|
||||
.composer {
|
||||
.starter {
|
||||
height: fit-content;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user