Fix token expiration error loop (#6731) (#8802)

Fixes issue https://github.com/twentyhq/twenty/issues/6731

**Problem:** After access token token expires, scrolling down the
`RecordTable` component will put it to an infinite loop of trying to
fetch records and printing errors on every iteration.

**Solution:** Disable fetching until component remount if a `FORBIDDEN`
error is encountered.

---------

Co-authored-by: ad-elias <elias@autodiligence.com>
This commit is contained in:
eliasylonen 2024-11-29 10:59:19 +01:00 committed by GitHub
parent 83223eeae3
commit c878f09d72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 3 deletions

View File

@ -188,6 +188,7 @@ export const useFetchMoreRecordsWithPagination = <
};
} catch (error) {
handleFindManyRecordsError(error as ApolloError);
return { error: error as ApolloError };
} finally {
setIsFetchingMoreObjects(false);
}

View File

@ -13,6 +13,8 @@ import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/
import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2';
import { isNonEmptyString } from '@sniptt/guards';
import { useScrollToPosition } from '~/hooks/useScrollToPosition';
import { tableEncounteredUnrecoverableErrorComponentState } from '@/object-record/record-table/states/tableEncounteredUnrecoverableErrorComponentState';
import { useRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentStateV2';
export const RecordTableNoRecordGroupBodyEffect = () => {
const { objectNameSingular } = useContext(RecordTableContext);
@ -37,6 +39,9 @@ export const RecordTableNoRecordGroupBodyEffect = () => {
tableLastRowVisibleComponentState,
);
const [encounteredUnrecoverableError, setEncounteredUnrecoverableError] =
useRecoilComponentStateV2(tableEncounteredUnrecoverableErrorComponentState);
const setHasRecordTableFetchedAllRecordsComponents =
useSetRecoilComponentStateV2(
hasRecordTableFetchedAllRecordsComponentStateV2,
@ -86,7 +91,7 @@ export const RecordTableNoRecordGroupBodyEffect = () => {
const fetchMoreDebouncedIfRequested = useDebouncedCallback(async () => {
// We are debouncing here to give the user some room to scroll if they want to within this throttle window
await fetchMoreRecords();
return await fetchMoreRecords();
}, 100);
useEffect(() => {
@ -97,8 +102,22 @@ export const RecordTableNoRecordGroupBodyEffect = () => {
useEffect(() => {
(async () => {
if (!isFetchingMoreObjects && tableLastRowVisible && hasNextPage) {
await fetchMoreDebouncedIfRequested();
if (
!isFetchingMoreObjects &&
tableLastRowVisible &&
hasNextPage &&
!encounteredUnrecoverableError
) {
const result = await fetchMoreDebouncedIfRequested();
const isForbidden =
result?.error?.graphQLErrors.some(
(e) => e.extensions?.code === 'FORBIDDEN',
) ?? false;
if (isForbidden) {
setEncounteredUnrecoverableError(true);
}
}
})();
}, [
@ -109,6 +128,8 @@ export const RecordTableNoRecordGroupBodyEffect = () => {
fetchMoreDebouncedIfRequested,
isFetchingMoreObjects,
tableLastRowVisible,
encounteredUnrecoverableError,
setEncounteredUnrecoverableError,
]);
return <></>;

View File

@ -0,0 +1,9 @@
import { RecordTableComponentInstanceContext } from '@/object-record/record-table/states/context/RecordTableComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
export const tableEncounteredUnrecoverableErrorComponentState =
createComponentStateV2<boolean>({
key: 'tableEncounteredUnrecoverableErrorComponentState',
defaultValue: false,
componentInstanceContext: RecordTableComponentInstanceContext,
});