refactor(core): standardize frontend error handling (#10667)

This commit is contained in:
forehalo
2025-03-06 13:10:18 +00:00
parent 2e86bfffae
commit e02fb4fa94
70 changed files with 495 additions and 480 deletions
@@ -15,6 +15,7 @@ import {
SubscriptionService,
} from '@affine/core/modules/cloud';
import { UrlService } from '@affine/core/modules/url';
import { UserFriendlyError } from '@affine/error';
import type { InvoicesQuery } from '@affine/graphql';
import {
createCustomerPortalMutation,
@@ -22,7 +23,6 @@ import {
SubscriptionPlan,
SubscriptionRecurring,
SubscriptionStatus,
UserFriendlyError,
} from '@affine/graphql';
import { type I18nString, i18nTime, Trans, useI18n } from '@affine/i18n';
import { track } from '@affine/track';
@@ -539,8 +539,8 @@ const BillingHistory = () => {
return (
<span style={{ color: cssVar('errorColor') }}>
{error
? UserFriendlyError.fromAnyError(error).message
: 'Failed to load members'}
? UserFriendlyError.fromAny(error).message
: 'Failed to load invoices'}
</span>
);
}
@@ -17,13 +17,13 @@ import {
import { WorkspaceQuotaService } from '@affine/core/modules/quota';
import { UrlService } from '@affine/core/modules/url';
import { WorkspaceService } from '@affine/core/modules/workspace';
import { UserFriendlyError } from '@affine/error';
import {
createCustomerPortalMutation,
type InvoicesQuery,
InvoiceStatus,
SubscriptionPlan,
SubscriptionRecurring,
UserFriendlyError,
} from '@affine/graphql';
import { useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
@@ -321,8 +321,8 @@ const BillingHistory = () => {
return (
<span style={{ color: cssVar('errorColor') }}>
{error
? UserFriendlyError.fromAnyError(error).message
: 'Failed to load members'}
? UserFriendlyError.fromAny(error).message
: 'Failed to load invoices'}
</span>
);
}
@@ -8,7 +8,7 @@ import {
import { WorkspacePermissionService } from '@affine/core/modules/permissions';
import { WorkspaceQuotaService } from '@affine/core/modules/quota';
import { WorkspaceService } from '@affine/core/modules/workspace';
import { UserFriendlyError } from '@affine/graphql';
import { UserFriendlyError } from '@affine/error';
import { Trans, useI18n } from '@affine/i18n';
import { useLiveData, useService } from '@toeverything/infra';
import clsx from 'clsx';
@@ -91,7 +91,7 @@ export const SelfHostTeamCard = () => {
setLoading(false);
console.error(e);
const error = UserFriendlyError.fromAnyError(e);
const error = UserFriendlyError.fromAny(e);
notify.error({
title: error.name,
@@ -119,7 +119,7 @@ export const SelfHostTeamCard = () => {
setLoading(false);
console.error(e);
const error = UserFriendlyError.fromAnyError(e);
const error = UserFriendlyError.fromAny(e);
notify.error({
title: error.name,
@@ -20,12 +20,9 @@ import { WorkspaceQuotaService } from '@affine/core/modules/quota';
import { WorkspaceShareSettingService } from '@affine/core/modules/share-setting';
import { copyTextToClipboard } from '@affine/core/utils/clipboard';
import { emailRegex } from '@affine/core/utils/email-regex';
import { UserFriendlyError } from '@affine/error';
import type { WorkspaceInviteLinkExpireTime } from '@affine/graphql';
import {
ServerDeploymentType,
SubscriptionPlan,
UserFriendlyError,
} from '@affine/graphql';
import { ServerDeploymentType, SubscriptionPlan } from '@affine/graphql';
import { useI18n } from '@affine/i18n';
import { track } from '@affine/track';
import { ExportIcon } from '@blocksuite/icons/rc';
@@ -129,7 +126,7 @@ export const CloudWorkspaceMembersPanel = ({
message: t['com.affine.payment.resume.success.team.message'](),
});
} catch (err) {
const error = UserFriendlyError.fromAnyError(err);
const error = UserFriendlyError.fromAny(err);
notify.error({
title: error.name,
message: error.message,
@@ -299,7 +296,7 @@ export const CloudWorkspaceMembersPanel = ({
return (
<span className={styles.errorStyle}>
{error
? UserFriendlyError.fromAnyError(error).message
? UserFriendlyError.fromAny(error).message
: 'Failed to load members'}
</span>
);
@@ -6,11 +6,8 @@ import {
WorkspaceMembersService,
} from '@affine/core/modules/permissions';
import { WorkspaceService } from '@affine/core/modules/workspace';
import {
Permission,
UserFriendlyError,
WorkspaceMemberStatus,
} from '@affine/graphql';
import { UserFriendlyError } from '@affine/error';
import { Permission, WorkspaceMemberStatus } from '@affine/graphql';
import { type I18nString, useI18n } from '@affine/i18n';
import { MoreVerticalIcon } from '@blocksuite/icons/rc';
import {
@@ -75,7 +72,7 @@ export const MemberList = ({
) : (
<span className={styles.errorStyle}>
{error
? UserFriendlyError.fromAnyError(error).message
? UserFriendlyError.fromAny(error).message
: 'Failed to load members'}
</span>
)
@@ -1,8 +1,9 @@
import { Button } from '@affine/component';
import { AuthPageContainer } from '@affine/component/auth-components';
import { useNavigateHelper } from '@affine/core/components/hooks/use-navigate-helper';
import { BackendError, GraphQLService } from '@affine/core/modules/cloud';
import { changeEmailMutation, ErrorNames } from '@affine/graphql';
import { GraphQLService } from '@affine/core/modules/cloud';
import { UserFriendlyError } from '@affine/error';
import { changeEmailMutation } from '@affine/graphql';
import { useI18n } from '@affine/i18n';
import { useService } from '@toeverything/infra';
import { type FC, useEffect, useState } from 'react';
@@ -33,11 +34,8 @@ export const ConfirmChangeEmail: FC<{
},
})
.catch(err => {
if (err instanceof BackendError) {
const userFriendlyError = err.originError;
if (userFriendlyError.name === ErrorNames.INVALID_EMAIL_TOKEN) {
return navigateHelper.jumpToExpired();
}
if (UserFriendlyError.fromAny(err).is('INVALID_EMAIL_TOKEN')) {
return navigateHelper.jumpToExpired();
}
throw err;
})
@@ -2,11 +2,8 @@ import { Button } from '@affine/component';
import { AuthPageContainer } from '@affine/component/auth-components';
import { useNavigateHelper } from '@affine/core/components/hooks/use-navigate-helper';
import { GraphQLService } from '@affine/core/modules/cloud';
import {
ErrorNames,
UserFriendlyError,
verifyEmailMutation,
} from '@affine/graphql';
import { UserFriendlyError } from '@affine/error';
import { verifyEmailMutation } from '@affine/graphql';
import { useI18n } from '@affine/i18n';
import { useService } from '@toeverything/infra';
import { type FC, useEffect, useState } from 'react';
@@ -35,8 +32,8 @@ export const ConfirmVerifiedEmail: FC<{
},
})
.catch(error => {
const userFriendlyError = UserFriendlyError.fromAnyError(error);
if (userFriendlyError.name === ErrorNames.INVALID_EMAIL_TOKEN) {
const userFriendlyError = UserFriendlyError.fromAny(error);
if (userFriendlyError.is('INVALID_EMAIL_TOKEN')) {
return navigateHelper.jumpToExpired();
}
throw error;
@@ -3,7 +3,7 @@ import {
ExpiredPage,
JoinFailedPage,
} from '@affine/component/member-components';
import { ErrorNames, UserFriendlyError } from '@affine/graphql';
import { UserFriendlyError } from '@affine/error';
import { useLiveData, useService } from '@toeverything/infra';
import { useCallback, useEffect } from 'react';
import { Navigate, useParams } from 'react-router-dom';
@@ -43,8 +43,8 @@ const AcceptInvite = ({ inviteId: targetInviteId }: { inviteId: string }) => {
useEffect(() => {
if (error && inviteId === targetInviteId) {
const err = UserFriendlyError.fromAnyError(error);
if (err.name === ErrorNames.ALREADY_IN_SPACE) {
const err = UserFriendlyError.fromAny(error);
if (err.is('ALREADY_IN_SPACE')) {
return navigateHelper.jumpToIndex();
}
}
@@ -1,4 +1,5 @@
import { Button, Loading } from '@affine/component';
import { UserFriendlyError } from '@affine/error';
import {
SubscriptionPlan,
SubscriptionRecurring,
@@ -16,11 +17,7 @@ import {
RouteLogic,
useNavigateHelper,
} from '../../../components/hooks/use-navigate-helper';
import {
AuthService,
BackendError,
SubscriptionService,
} from '../../../modules/cloud';
import { AuthService, SubscriptionService } from '../../../modules/cloud';
import { container } from './subscribe.css';
interface ProductTriple {
@@ -160,12 +157,8 @@ export const Component = () => {
setMessage('Redirecting...');
location.href = checkout;
} catch (err) {
if (err instanceof BackendError) {
setMessage(err.originError.message);
} else {
console.log(err);
setError('Something went wrong, please contact support.');
}
const e = UserFriendlyError.fromAny(err);
setMessage(e.message);
}
}).pipe(mergeMap(() => EMPTY));
})