feat: handle copilot error (#7760)

fix BS-729 CLOUD-32 PD-1529
This commit is contained in:
darkskygit
2024-08-06 11:19:35 +00:00
parent 601f5fef95
commit 744cc542de
2 changed files with 53 additions and 16 deletions
@@ -106,12 +106,23 @@ export const PaymentRequiredErrorRenderer = (host: EditorHost) => html`
> >
`; `;
export const GeneralErrorRenderer = ( type ErrorProps = {
text: TemplateResult<1> = html`An error occurred, If this issue persists text?: TemplateResult<1>;
please let us know. template?: TemplateResult<1>;
<a href="mailto:support@toeverything.info"> support@toeverything.info </a>`, error?: TemplateResult<1>;
template: TemplateResult<1> = html`${nothing}` };
) => html` <ai-error-wrapper .text=${text}>${template}</ai-error-wrapper>`;
const generateText = (error?: TemplateResult<1>) =>
html`${error || 'An error occurred'}, If this issue persists please let us
know.<a href="mailto:support@toeverything.info">
support@toeverything.info
</a>`;
const nope = html`${nothing}`;
const GeneralErrorRenderer = (props: ErrorProps = {}) => {
const { text = generateText(props.error), template = nope } = props;
return html`<ai-error-wrapper .text=${text}>${template}</ai-error-wrapper>`;
};
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@@ -123,9 +134,9 @@ export function AIChatErrorRenderer(host: EditorHost, error: AIError) {
if (error instanceof PaymentRequiredError) { if (error instanceof PaymentRequiredError) {
return PaymentRequiredErrorRenderer(host); return PaymentRequiredErrorRenderer(host);
} else if (error instanceof UnauthorizedError) { } else if (error instanceof UnauthorizedError) {
return GeneralErrorRenderer( return GeneralErrorRenderer({
html`You need to login to AFFiNE Cloud to continue using AFFiNE AI.`, text: html`You need to login to AFFiNE Cloud to continue using AFFiNE AI.`,
html`<div template: html`<div
style=${styleMap({ style=${styleMap({
padding: '4px 12px', padding: '4px 12px',
borderRadius: '8px', borderRadius: '8px',
@@ -136,9 +147,31 @@ export function AIChatErrorRenderer(host: EditorHost, error: AIError) {
@click=${() => AIProvider.slots.requestLogin.emit({ host })} @click=${() => AIProvider.slots.requestLogin.emit({ host })}
> >
Login Login
</div>` </div>`,
); });
} else { } else {
return GeneralErrorRenderer(); const tip = error.message;
return GeneralErrorRenderer({
error: html`<style>
.tip {
position: relative;
cursor: pointer;
}
.tip:hover::after {
content: attr(data-tip);
position: absolute;
left: 0;
top: 20px;
background-color: black;
color: white;
padding: 5px 10px;
border-radius: 5px;
z-index: 1000;
white-space: pre;
}
</style>
<a class="tip" href="#" data-tip="${tip}">An error occurred</a>`,
});
} }
} }
@@ -25,14 +25,18 @@ import { getCurrentStore } from '@toeverything/infra';
type OptionsField<T extends GraphQLQuery> = type OptionsField<T extends GraphQLQuery> =
RequestOptions<T>['variables'] extends { options: infer U } ? U : never; RequestOptions<T>['variables'] extends { options: infer U } ? U : never;
function codeToError(code: number) { function codeToError(error: UserFriendlyError) {
switch (code) { switch (error.status) {
case 401: case 401:
return new UnauthorizedError(); return new UnauthorizedError();
case 402: case 402:
return new PaymentRequiredError(); return new PaymentRequiredError();
default: default:
return new GeneralNetworkError(); return new GeneralNetworkError(
error.code
? `${error.code}: ${error.message}\nIdentify: ${error.name}`
: undefined
);
} }
} }
@@ -42,7 +46,7 @@ export function resolveError(err: any) {
? new UserFriendlyError(err.extensions) ? new UserFriendlyError(err.extensions)
: UserFriendlyError.fromAnyError(err); : UserFriendlyError.fromAnyError(err);
return codeToError(standardError.status); return codeToError(standardError);
} }
export function handleError(src: any) { export function handleError(src: any) {