mirror of
https://github.com/logto-io/logto.git
synced 2025-02-24 22:05:56 -05:00
fix(console): improve swr error handling to avoid app crash
This commit is contained in:
parent
5d34442018
commit
da77a1d1b5
13 changed files with 25 additions and 25 deletions
|
@ -9,7 +9,7 @@ import { toast } from 'react-hot-toast';
|
||||||
import { logtoApiResource } from '@/consts/api';
|
import { logtoApiResource } from '@/consts/api';
|
||||||
|
|
||||||
export class RequestError extends Error {
|
export class RequestError extends Error {
|
||||||
body: RequestErrorBody;
|
body?: RequestErrorBody;
|
||||||
|
|
||||||
constructor(body: RequestErrorBody) {
|
constructor(body: RequestErrorBody) {
|
||||||
super('Request error occurred.');
|
super('Request error occurred.');
|
||||||
|
|
|
@ -84,7 +84,7 @@ const ApiResourceDetails = () => {
|
||||||
className={styles.backLink}
|
className={styles.backLink}
|
||||||
/>
|
/>
|
||||||
{isLoading && <DetailsSkeleton />}
|
{isLoading && <DetailsSkeleton />}
|
||||||
{error && <div>{`error occurred: ${error.body.message}`}</div>}
|
{!data && error && <div>{`error occurred: ${error.body?.message ?? error.message}`}</div>}
|
||||||
{data && (
|
{data && (
|
||||||
<>
|
<>
|
||||||
<Card className={styles.header}>
|
<Card className={styles.header}>
|
||||||
|
|
|
@ -85,10 +85,10 @@ const ApiResources = () => {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{error && (
|
{!data && error && (
|
||||||
<TableError
|
<TableError
|
||||||
columns={2}
|
columns={2}
|
||||||
content={error.body.message}
|
content={error.body?.message ?? error.message}
|
||||||
onRetry={async () => mutate(undefined, true)}
|
onRetry={async () => mutate(undefined, true)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -82,10 +82,10 @@ const Applications = () => {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{error && (
|
{!data && error && (
|
||||||
<TableError
|
<TableError
|
||||||
columns={2}
|
columns={2}
|
||||||
content={error.body.message}
|
content={error.body?.message ?? error.message}
|
||||||
onRetry={async () => mutate(undefined, true)}
|
onRetry={async () => mutate(undefined, true)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -107,7 +107,7 @@ const ConnectorDetails = () => {
|
||||||
className={styles.backLink}
|
className={styles.backLink}
|
||||||
/>
|
/>
|
||||||
{isLoading && <DetailsSkeleton />}
|
{isLoading && <DetailsSkeleton />}
|
||||||
{error && <div>{`error occurred: ${error.body.message}`}</div>}
|
{!data && error && <div>{`error occurred: ${error.body?.message ?? error.message}`}</div>}
|
||||||
{data && (
|
{data && (
|
||||||
<Card className={styles.header}>
|
<Card className={styles.header}>
|
||||||
<div className={styles.imagePlaceholder}>
|
<div className={styles.imagePlaceholder}>
|
||||||
|
|
|
@ -85,10 +85,10 @@ const Connectors = () => {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{error && (
|
{!data && error && (
|
||||||
<TableError
|
<TableError
|
||||||
columns={3}
|
columns={3}
|
||||||
content={error.body.message}
|
content={error.body?.message ?? error.message}
|
||||||
onRetry={async () => mutate(undefined, true)}
|
onRetry={async () => mutate(undefined, true)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -60,7 +60,7 @@ const Settings = () => {
|
||||||
<TabNavItem href="/settings">{t('settings.tabs.general')}</TabNavItem>
|
<TabNavItem href="/settings">{t('settings.tabs.general')}</TabNavItem>
|
||||||
</TabNav>
|
</TabNav>
|
||||||
{!data && !error && <div>loading</div>}
|
{!data && !error && <div>loading</div>}
|
||||||
{error && <div>{`error occurred: ${error.body.message}`}</div>}
|
{!data && error && <div>{`error occurred: ${error.body?.message ?? error.message}`}</div>}
|
||||||
{data && (
|
{data && (
|
||||||
<form className={detailsStyles.body} onSubmit={onSubmit}>
|
<form className={detailsStyles.body} onSubmit={onSubmit}>
|
||||||
<div className={styles.fields}>
|
<div className={styles.fields}>
|
||||||
|
|
|
@ -26,8 +26,8 @@ const ConnectorsTransfer = ({ value, onChange }: Props) => {
|
||||||
return <div>loading</div>;
|
return <div>loading</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (!data && error) {
|
||||||
<div>{`error occurred: ${error.body.message}`}</div>;
|
<div>{`error occurred: ${error.body?.message ?? error.message}`}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const datasource = data
|
const datasource = data
|
||||||
|
|
|
@ -42,7 +42,7 @@ const SignInMethodsPreview = ({ data }: Props) => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{!connectors && !error && <div>loading</div>}
|
{!connectors && !error && <div>loading</div>}
|
||||||
{error && <div>{error.body.message}</div>}
|
{!connectors && error && <div>{error.body?.message ?? error.message}</div>}
|
||||||
{connectors &&
|
{connectors &&
|
||||||
Object.values(SignInMethodKey)
|
Object.values(SignInMethodKey)
|
||||||
.filter((key) => signInMethods[key] !== SignInMethodState.Disabled)
|
.filter((key) => signInMethods[key] !== SignInMethodState.Disabled)
|
||||||
|
|
|
@ -84,8 +84,8 @@ const SignInExperience = () => {
|
||||||
return <div>loading</div>;
|
return <div>loading</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configError) {
|
if (!configs && configError) {
|
||||||
return <div>{configError.body.message}</div>;
|
return <div>{configError.body?.message ?? configError.message}</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (configs?.customizeSignInExperience) {
|
if (configs?.customizeSignInExperience) {
|
||||||
|
@ -109,7 +109,7 @@ const SignInExperience = () => {
|
||||||
</TabNavItem>
|
</TabNavItem>
|
||||||
</TabNav>
|
</TabNav>
|
||||||
{!data && !error && <div>loading</div>}
|
{!data && !error && <div>loading</div>}
|
||||||
{error && <div>{`error occurred: ${error.body.message}`}</div>}
|
{!data && error && <div>{`error occurred: ${error.body?.message ?? error.message}`}</div>}
|
||||||
{data && (
|
{data && (
|
||||||
<FormProvider {...methods}>
|
<FormProvider {...methods}>
|
||||||
<form onSubmit={onSubmit}>
|
<form onSubmit={onSubmit}>
|
||||||
|
|
|
@ -31,20 +31,20 @@ const UserConnectors = ({ userId, connectors, onDelete }: Props) => {
|
||||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||||
const { data, error, mutate } = useSWR<ConnectorDTO[], RequestError>('/api/connectors');
|
const { data, error, mutate } = useSWR<ConnectorDTO[], RequestError>('/api/connectors');
|
||||||
const isLoading = !data && !error;
|
const isLoading = !data && !error;
|
||||||
const [isSubmiting, setIsSubmiting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
|
|
||||||
const handleDelete = async (connectorId: string) => {
|
const handleDelete = async (connectorId: string) => {
|
||||||
if (isSubmiting) {
|
if (isSubmitting) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsSubmiting(true);
|
setIsSubmitting(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await api.delete(`/api/users/${userId}/identities/${connectorId}`);
|
await api.delete(`/api/users/${userId}/identities/${connectorId}`);
|
||||||
onDelete?.(connectorId);
|
onDelete?.(connectorId);
|
||||||
} finally {
|
} finally {
|
||||||
setIsSubmiting(false);
|
setIsSubmitting(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -96,10 +96,10 @@ const UserConnectors = ({ userId, connectors, onDelete }: Props) => {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{error && (
|
{!data && error && (
|
||||||
<TableError
|
<TableError
|
||||||
columns={3}
|
columns={3}
|
||||||
content={error.body.message}
|
content={error.body?.message ?? error.message}
|
||||||
onRetry={async () => mutate(undefined, true)}
|
onRetry={async () => mutate(undefined, true)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -113,7 +113,7 @@ const UserDetails = () => {
|
||||||
className={styles.backLink}
|
className={styles.backLink}
|
||||||
/>
|
/>
|
||||||
{isLoading && <DetailsSkeleton />}
|
{isLoading && <DetailsSkeleton />}
|
||||||
{error && <div>{`error occurred: ${error.body.message}`}</div>}
|
{!data && error && <div>{`error occurred: ${error.body?.message ?? error.message}`}</div>}
|
||||||
{id && data && (
|
{id && data && (
|
||||||
<>
|
<>
|
||||||
<Card className={styles.header}>
|
<Card className={styles.header}>
|
||||||
|
|
|
@ -95,10 +95,10 @@ const Users = () => {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{error && (
|
{!data && error && (
|
||||||
<TableError
|
<TableError
|
||||||
columns={3}
|
columns={3}
|
||||||
content={error.body.message}
|
content={error.body?.message ?? error.message}
|
||||||
onRetry={async () => mutate(undefined, true)}
|
onRetry={async () => mutate(undefined, true)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
Loading…
Add table
Reference in a new issue