mirror of
https://github.com/logto-io/logto.git
synced 2025-04-07 23:01:25 -05:00
fix(console): catch user interaction errors (#3591)
This commit is contained in:
parent
93bc915609
commit
875d94a02a
5 changed files with 36 additions and 28 deletions
|
@ -1,11 +1,14 @@
|
|||
import { useLogto } from '@logto/react';
|
||||
import type { TenantInfo } from '@logto/schemas';
|
||||
import { conditional, yes } from '@silverhand/essentials';
|
||||
import { useContext, useEffect } from 'react';
|
||||
import { HTTPError } from 'ky';
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import { useHref, useSearchParams } from 'react-router-dom';
|
||||
|
||||
import { useCloudApi } from '@/cloud/hooks/use-cloud-api';
|
||||
import AppError from '@/components/AppError';
|
||||
import AppLoading from '@/components/AppLoading';
|
||||
import SessionExpired from '@/components/SessionExpired';
|
||||
import { searchKeys } from '@/consts';
|
||||
import { TenantsContext } from '@/contexts/TenantsProvider';
|
||||
|
||||
|
@ -15,11 +18,18 @@ import Tenants from './Tenants';
|
|||
function Protected() {
|
||||
const api = useCloudApi();
|
||||
const { tenants, setTenants, currentTenantId } = useContext(TenantsContext);
|
||||
const [error, setError] = useState<Error>();
|
||||
|
||||
useEffect(() => {
|
||||
const loadTenants = async () => {
|
||||
const data = await api.get('/api/tenants').json<TenantInfo[]>();
|
||||
setTenants(data);
|
||||
setError(undefined);
|
||||
|
||||
try {
|
||||
const data = await api.get('/api/tenants').json<TenantInfo[]>();
|
||||
setTenants(data);
|
||||
} catch (error: unknown) {
|
||||
setError(error instanceof Error ? error : new Error(String(error)));
|
||||
}
|
||||
};
|
||||
|
||||
if (!tenants) {
|
||||
|
@ -27,6 +37,14 @@ function Protected() {
|
|||
}
|
||||
}, [api, setTenants, tenants]);
|
||||
|
||||
if (error) {
|
||||
if (error instanceof HTTPError && error.response.status === 401) {
|
||||
return <SessionExpired error={error} />;
|
||||
}
|
||||
|
||||
return <AppError errorMessage={error.message} callStack={error.stack} />;
|
||||
}
|
||||
|
||||
if (tenants) {
|
||||
if (currentTenantId) {
|
||||
return <Redirect tenants={tenants} toTenantId={currentTenantId} />;
|
||||
|
|
|
@ -12,7 +12,7 @@ type Props = {
|
|||
};
|
||||
|
||||
function SessionExpired({ callbackHref = '/callback', error }: Props) {
|
||||
const { signIn, signOut } = useLogto();
|
||||
const { signIn } = useLogto();
|
||||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
|
||||
return (
|
||||
|
|
|
@ -45,8 +45,8 @@ class ErrorBoundary extends Component<Props, State> {
|
|||
const { error } = this.state;
|
||||
|
||||
if (error) {
|
||||
if (error instanceof HTTPError && error.response.status === 401) {
|
||||
return <SessionExpired error={error} />;
|
||||
if (error instanceof HTTPError) {
|
||||
return error.response.status === 401 ? <SessionExpired error={error} /> : children;
|
||||
}
|
||||
|
||||
const callStack = conditional(
|
||||
|
|
|
@ -63,12 +63,8 @@ function SenderTester({ connectorFactoryId, connectorType, className, parse }: P
|
|||
: { email: sendTo }),
|
||||
};
|
||||
|
||||
try {
|
||||
await api.post(`api/connectors/${connectorFactoryId}/test`, { json: data }).json();
|
||||
setShowTooltip(true);
|
||||
} catch (error: unknown) {
|
||||
console.error(error);
|
||||
}
|
||||
await api.post(`api/connectors/${connectorFactoryId}/test`, { json: data }).json();
|
||||
setShowTooltip(true);
|
||||
});
|
||||
|
||||
return (
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
import type { ConnectorResponse } from '@logto/schemas';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import useSWRImmutable from 'swr/immutable';
|
||||
|
||||
import Button from '@/components/Button';
|
||||
import CardTitle from '@/components/CardTitle';
|
||||
import FormCard from '@/components/FormCard';
|
||||
import { adminTenantEndpoint, meApi } from '@/consts';
|
||||
import { isCloud } from '@/consts/cloud';
|
||||
import type { RequestError } from '@/hooks/use-api';
|
||||
import { useStaticApi } from '@/hooks/use-api';
|
||||
import useCurrentUser from '@/hooks/use-current-user';
|
||||
import useSwrFetcher from '@/hooks/use-swr-fetcher';
|
||||
import useUserAssetsService from '@/hooks/use-user-assets-service';
|
||||
import * as resourcesStyles from '@/scss/resources.module.scss';
|
||||
import { withAppInsights } from '@/utils/app-insights';
|
||||
|
@ -26,27 +29,18 @@ function Profile() {
|
|||
const { t } = useTranslation(undefined, { keyPrefix: 'admin_console' });
|
||||
const navigate = useNavigate();
|
||||
const api = useStaticApi({ prefixUrl: adminTenantEndpoint, resourceIndicator: meApi.indicator });
|
||||
const fetcher = useSwrFetcher<ConnectorResponse[]>(api);
|
||||
const { data: connectors, error: fetchConnectorsError } = useSWRImmutable<
|
||||
ConnectorResponse[],
|
||||
RequestError
|
||||
>('me/social/connectors', fetcher);
|
||||
const isLoadingConnectors = !connectors && !fetchConnectorsError;
|
||||
const { user, reload, isLoading: isLoadingUser } = useCurrentUser();
|
||||
const { isLoading: isUserAssetServiceLoading } = useUserAssetsService();
|
||||
|
||||
const [connectors, setConnectors] = useState<ConnectorResponse[]>();
|
||||
const [isLoadingConnectors, setIsLoadingConnectors] = useState(false);
|
||||
const [showDeleteAccountModal, setShowDeleteAccountModal] = useState(false);
|
||||
|
||||
const showLoadingSkeleton = isLoadingUser || isLoadingConnectors || isUserAssetServiceLoading;
|
||||
|
||||
useEffect(() => {
|
||||
void reload();
|
||||
|
||||
(async () => {
|
||||
setIsLoadingConnectors(true);
|
||||
const connectorResponse = await api.get('me/social/connectors').json<ConnectorResponse[]>();
|
||||
|
||||
setConnectors(connectorResponse);
|
||||
setIsLoadingConnectors(false);
|
||||
})();
|
||||
}, [api, reload]);
|
||||
|
||||
return (
|
||||
<div className={resourcesStyles.container}>
|
||||
<div className={resourcesStyles.headline}>
|
||||
|
|
Loading…
Add table
Reference in a new issue