diff --git a/native/data/core-data-provider.react.js b/native/data/core-data-provider.react.js --- a/native/data/core-data-provider.react.js +++ b/native/data/core-data-provider.react.js @@ -4,6 +4,7 @@ import { useSelector } from 'react-redux'; import { commCoreModule } from '../native-modules'; +import { checkIfTaskWasCancelled } from '../utils/error-handling'; import { type CoreData, defaultCoreData, CoreDataContext } from './core-data'; type Props = { @@ -16,21 +17,27 @@ React.useEffect(() => { (async () => { - const fetchedDrafts = await commCoreModule.getAllDrafts(); - setDraftCache(prevDrafts => { - const mergedDrafts = {}; - for (const draftObj of fetchedDrafts) { - mergedDrafts[draftObj.key] = draftObj.text; - } - for (const key in prevDrafts) { - const value = prevDrafts[key]; - if (!value) { - continue; + try { + const fetchedDrafts = await commCoreModule.getAllDrafts(); + setDraftCache(prevDrafts => { + const mergedDrafts = {}; + for (const draftObj of fetchedDrafts) { + mergedDrafts[draftObj.key] = draftObj.text; } - mergedDrafts[key] = value; + for (const key in prevDrafts) { + const value = prevDrafts[key]; + if (!value) { + continue; + } + mergedDrafts[key] = value; + } + return mergedDrafts; + }); + } catch (e) { + if (!checkIfTaskWasCancelled(e)) { + throw e; } - return mergedDrafts; - }); + } })(); }, []); @@ -41,7 +48,9 @@ return await commCoreModule.removeAllDrafts(); } catch (e) { setDraftCache(oldDrafts); - throw e; + if (!checkIfTaskWasCancelled(e)) { + throw e; + } } }, [draftCache]); @@ -92,6 +101,9 @@ return await commCoreModule.updateDraft(draft); } catch (e) { setDrafts([{ key: draft.key, text: prevDraftText }]); + if (checkIfTaskWasCancelled(e)) { + return false; + } throw e; } }, @@ -115,6 +127,9 @@ { key: newKey, text: null }, { key: prevKey, text: value }, ]); + if (checkIfTaskWasCancelled(e)) { + return false; + } throw e; } }, diff --git a/native/data/core-data.js b/native/data/core-data.js --- a/native/data/core-data.js +++ b/native/data/core-data.js @@ -5,12 +5,14 @@ import { draftKeyFromThreadID } from 'lib/shared/thread-utils'; import { commCoreModule } from '../native-modules'; +import { checkIfTaskWasCancelled } from '../utils/error-handling'; -export type UpdateDraft = (draft: { +type DraftType = { +key: string, +text: string, -}) => Promise; +}; +export type UpdateDraft = (draft: DraftType) => Promise; export type MoveDraft = (prevKey: string, nextKey: string) => Promise; export type CoreData = { @@ -24,8 +26,26 @@ const defaultCoreData = Object.freeze({ drafts: { data: ({}: { +[key: string]: string }), - updateDraft: commCoreModule.updateDraft, - moveDraft: commCoreModule.moveDraft, + updateDraft: async (draft: DraftType): Promise => { + try { + return commCoreModule.updateDraft(draft); + } catch (e) { + if (!checkIfTaskWasCancelled(e)) { + throw e; + } + } + return false; + }, + moveDraft: async (prevKey: string, nextKey: string): Promise => { + try { + return commCoreModule.moveDraft(prevKey, nextKey); + } catch (e) { + if (!checkIfTaskWasCancelled(e)) { + throw e; + } + } + return false; + }, }, }); diff --git a/native/data/sensitive-data-handler.react.js b/native/data/sensitive-data-handler.react.js --- a/native/data/sensitive-data-handler.react.js +++ b/native/data/sensitive-data-handler.react.js @@ -5,6 +5,7 @@ import { commCoreModule } from '../native-modules'; import { useSelector } from '../redux/redux-utils'; +import { checkIfTaskWasCancelled } from '../utils/error-handling'; function SensitiveDataHandler(): null { const currentLoggedInUserID: ?string = useSelector(state => @@ -28,6 +29,9 @@ await commCoreModule.setDeviceID('MOBILE'); } } catch (e) { + if (checkIfTaskWasCancelled(e)) { + return; + } if (__DEV__) { throw e; } else { diff --git a/native/data/sqlite-context-provider.js b/native/data/sqlite-context-provider.js --- a/native/data/sqlite-context-provider.js +++ b/native/data/sqlite-context-provider.js @@ -15,6 +15,7 @@ import { commCoreModule } from '../native-modules'; import { useSelector } from '../redux/redux-utils'; +import { checkIfTaskWasCancelled } from '../utils/error-handling'; import { useStaffCanSee } from '../utils/staff-utils'; import { SQLiteContext } from './sqlite-context'; @@ -61,6 +62,10 @@ }); setStoreLoaded(true); } catch (setStoreException) { + if (checkIfTaskWasCancelled(setStoreException)) { + setStoreLoaded(true); + return; + } if (staffCanSee) { Alert.alert( `Error setting threadStore or messageStore: ${ diff --git a/native/redux/persist.js b/native/redux/persist.js --- a/native/redux/persist.js +++ b/native/redux/persist.js @@ -27,6 +27,7 @@ import { defaultNotifPermissionAlertInfo } from '../push/alerts'; import { defaultDeviceCameraInfo } from '../types/camera'; import { defaultGlobalThemeInfo } from '../types/themes'; +import { checkIfTaskWasCancelled } from '../utils/error-handling'; import { migrateThreadStoreForEditThreadPermissions } from './edit-thread-permission-migration'; import type { AppState } from './state-types'; @@ -206,10 +207,16 @@ [22]: state => { for (const key in state.drafts) { const value = state.drafts[key]; - commCoreModule.updateDraft({ - key, - text: value, - }); + try { + commCoreModule.updateDraft({ + key, + text: value, + }); + } catch (e) { + if (!checkIfTaskWasCancelled(e)) { + throw e; + } + } } return { ...state, @@ -346,6 +353,9 @@ ); } catch (exception) { console.log(exception); + if (checkIfTaskWasCancelled(exception)) { + return state; + } return { ...state, cookie: null }; } return state; @@ -365,6 +375,9 @@ commCoreModule.processMessageStoreOperationsSync(operations); } catch (exception) { console.log(exception); + if (checkIfTaskWasCancelled(exception)) { + return state; + } return { ...state, cookie: null }; } return state; diff --git a/native/redux/redux-setup.js b/native/redux/redux-setup.js --- a/native/redux/redux-setup.js +++ b/native/redux/redux-setup.js @@ -47,6 +47,7 @@ import { defaultDeviceCameraInfo } from '../types/camera'; import { defaultConnectivityInfo } from '../types/connectivity'; import { defaultGlobalThemeInfo } from '../types/themes'; +import { checkIfTaskWasCancelled } from '../utils/error-handling'; import { isStaffRelease } from '../utils/staff-utils'; import { defaultURLPrefix, @@ -382,7 +383,10 @@ ); } await Promise.all(promises); - } catch { + } catch (e) { + if (checkIfTaskWasCancelled(e)) { + return; + } dispatch({ type: setNewSessionActionType, payload: { diff --git a/native/utils/error-handling.js b/native/utils/error-handling.js new file mode 100644 --- /dev/null +++ b/native/utils/error-handling.js @@ -0,0 +1,9 @@ +// @flow + +const TASK_CANCELLED_FLAG = 'TASK_CANCELLED'; + +function checkIfTaskWasCancelled(error: Error): boolean { + return error.message?.includes(TASK_CANCELLED_FLAG); +} + +export { checkIfTaskWasCancelled };