feat: moved frontend errors to redux

pull/3056/head
William Grant 1 year ago
parent 4de3570492
commit baca07a83b

@ -5,6 +5,7 @@ import { ONBOARDING_TIMES } from '../../../session/constants';
import { trigger } from '../../../shims/events'; import { trigger } from '../../../shims/events';
import { import {
AccountRestoration, AccountRestoration,
resetOnboardingState,
setAccountRestorationStep, setAccountRestorationStep,
} from '../../../state/onboarding/ducks/registration'; } from '../../../state/onboarding/ducks/registration';
@ -89,6 +90,7 @@ export const useRecoveryProgressEffect = (props: UseRecoveryProgressEffectProps)
window.log.debug( window.log.debug(
`WIP: [continueYourSession] AccountRestoration.Complete opening inbox for ${displayName}` `WIP: [continueYourSession] AccountRestoration.Complete opening inbox for ${displayName}`
); );
dispatch(resetOnboardingState());
trigger('openInbox'); trigger('openInbox');
} }
} }

@ -1,4 +1,4 @@
import { useEffect, useState } from 'react'; import { useEffect } from 'react';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { useMount } from 'react-use'; import { useMount } from 'react-use';
import { SettingsKey } from '../../../data/settings-key'; import { SettingsKey } from '../../../data/settings-key';
@ -10,11 +10,13 @@ import {
AccountCreation, AccountCreation,
setAccountCreationStep, setAccountCreationStep,
setDisplayName, setDisplayName,
setDisplayNameError,
setHexGeneratedPubKey, setHexGeneratedPubKey,
setRecoveryPassword, setRecoveryPassword,
} from '../../../state/onboarding/ducks/registration'; } from '../../../state/onboarding/ducks/registration';
import { import {
useDisplayName, useDisplayName,
useDisplayNameError,
useOnboardAccountCreationStep, useOnboardAccountCreationStep,
useOnboardHexGeneratedPubKey, useOnboardHexGeneratedPubKey,
useRecoveryPassword, useRecoveryPassword,
@ -57,12 +59,11 @@ export const CreateAccount = () => {
const step = useOnboardAccountCreationStep(); const step = useOnboardAccountCreationStep();
const recoveryPassword = useRecoveryPassword(); const recoveryPassword = useRecoveryPassword();
const hexGeneratedPubKey = useOnboardHexGeneratedPubKey(); const hexGeneratedPubKey = useOnboardHexGeneratedPubKey();
const displayName = useDisplayName();
const displayNameError = useDisplayNameError();
const dispatch = useDispatch(); const dispatch = useDispatch();
const displayName = useDisplayName();
const [displayNameError, setDisplayNameError] = useState<undefined | string>('');
const generateMnemonicAndKeyPair = async () => { const generateMnemonicAndKeyPair = async () => {
if (recoveryPassword === '') { if (recoveryPassword === '') {
const mnemonic = await generateMnemonic(); const mnemonic = await generateMnemonic();
@ -103,7 +104,7 @@ export const CreateAccount = () => {
displayName, displayName,
recoveryPassword, recoveryPassword,
errorCallback: e => { errorCallback: e => {
setDisplayNameError(e.message || String(e)); dispatch(setDisplayNameError(e.message || String(e)));
throw e; throw e;
}, },
}); });
@ -123,7 +124,7 @@ export const CreateAccount = () => {
callback={() => { callback={() => {
dispatch(setDisplayName('')); dispatch(setDisplayName(''));
dispatch(setRecoveryPassword('')); dispatch(setRecoveryPassword(''));
setDisplayNameError(''); dispatch(setDisplayNameError(undefined));
}} }}
> >
<Flex <Flex
@ -144,7 +145,7 @@ export const CreateAccount = () => {
placeholder={window.i18n('enterDisplayName')} placeholder={window.i18n('enterDisplayName')}
value={displayName} value={displayName}
onValueChanged={(_name: string) => { onValueChanged={(_name: string) => {
const name = sanitizeDisplayNameOrToast(_name, setDisplayNameError); const name = sanitizeDisplayNameOrToast(_name, setDisplayNameError, dispatch);
dispatch(setDisplayName(name)); dispatch(setDisplayName(name));
}} }}
onEnterPressed={signUpWithDetails} onEnterPressed={signUpWithDetails}

@ -1,4 +1,3 @@
import { useState } from 'react';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { ONBOARDING_TIMES } from '../../../session/constants'; import { ONBOARDING_TIMES } from '../../../session/constants';
import { InvalidWordsError, NotEnoughWordsError } from '../../../session/crypto/mnemonic'; import { InvalidWordsError, NotEnoughWordsError } from '../../../session/crypto/mnemonic';
@ -9,14 +8,18 @@ import {
AccountRestoration, AccountRestoration,
setAccountRestorationStep, setAccountRestorationStep,
setDisplayName, setDisplayName,
setDisplayNameError,
setProgress, setProgress,
setRecoveryPassword, setRecoveryPassword,
setRecoveryPasswordError,
} from '../../../state/onboarding/ducks/registration'; } from '../../../state/onboarding/ducks/registration';
import { import {
useDisplayName, useDisplayName,
useDisplayNameError,
useOnboardAccountRestorationStep, useOnboardAccountRestorationStep,
useProgress, useProgress,
useRecoveryPassword, useRecoveryPassword,
useRecoveryPasswordError,
} from '../../../state/onboarding/selectors/registration'; } from '../../../state/onboarding/selectors/registration';
import { import {
registerSingleDevice, registerSingleDevice,
@ -113,15 +116,10 @@ async function signInAndFetchDisplayName(
export const RestoreAccount = () => { export const RestoreAccount = () => {
const step = useOnboardAccountRestorationStep(); const step = useOnboardAccountRestorationStep();
const recoveryPassword = useRecoveryPassword(); const recoveryPassword = useRecoveryPassword();
const [recoveryPasswordError, setRecoveryPasswordError] = useState( const recoveryPasswordError = useRecoveryPasswordError();
undefined as string | undefined
);
const displayName = useDisplayName(); const displayName = useDisplayName();
const [displayNameError, setDisplayNameError] = useState<undefined | string>(''); const displayNameError = useDisplayNameError();
const progress = useProgress(); const progress = useProgress();
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -148,7 +146,6 @@ export const RestoreAccount = () => {
await registrationDone(ourPubkey, displayName); await registrationDone(ourPubkey, displayName);
dispatch(setAccountRestorationStep(AccountRestoration.Finishing)); dispatch(setAccountRestorationStep(AccountRestoration.Finishing));
} catch (e) { } catch (e) {
window.log.debug(`WIP: [recoverAndFetchDisplayName] error ${JSON.stringify(e)} `);
if (e instanceof NotFoundError || e instanceof TaskTimedOutError) { if (e instanceof NotFoundError || e instanceof TaskTimedOutError) {
window.log.debug( window.log.debug(
`WIP: [recoverAndFetchDisplayName] AccountRestoration.RecoveryPassword failed to get a display name so we need to enter it manually. Error: ${e}` `WIP: [recoverAndFetchDisplayName] AccountRestoration.RecoveryPassword failed to get a display name so we need to enter it manually. Error: ${e}`
@ -158,22 +155,16 @@ export const RestoreAccount = () => {
} }
if (e instanceof NotEnoughWordsError) { if (e instanceof NotEnoughWordsError) {
setRecoveryPasswordError(window.i18n('recoveryPasswordErrorMessageShort')); dispatch(setRecoveryPasswordError(window.i18n('recoveryPasswordErrorMessageShort')));
} else if (e instanceof InvalidWordsError) { } else if (e instanceof InvalidWordsError) {
setRecoveryPasswordError(window.i18n('recoveryPasswordErrorMessageIncorrect')); dispatch(setRecoveryPasswordError(window.i18n('recoveryPasswordErrorMessageIncorrect')));
} else { } else {
setRecoveryPasswordError(window.i18n('recoveryPasswordErrorMessageGeneric')); dispatch(setRecoveryPasswordError(window.i18n('recoveryPasswordErrorMessageGeneric')));
} }
window.log.debug( window.log.debug(
`WIP: [recoverAndFetchDisplayName] exception during registration: ${e.message || e} type ${typeof e}` `WIP: [recoverAndFetchDisplayName] exception during registration: ${e.message || e} type ${typeof JSON.stringify(e)}`
);
window.log.debug(
`WIP: [recoverAndFetchDisplayName] recoveryPasswordError before: ${recoveryPasswordError}`
); );
dispatch(setAccountRestorationStep(AccountRestoration.RecoveryPassword)); dispatch(setAccountRestorationStep(AccountRestoration.RecoveryPassword));
window.log.debug(
`WIP: [recoverAndFetchDisplayName] recoveryPasswordError after: ${recoveryPasswordError}`
);
} }
}; };
@ -188,7 +179,7 @@ export const RestoreAccount = () => {
displayName, displayName,
recoveryPassword, recoveryPassword,
errorCallback: e => { errorCallback: e => {
setDisplayNameError(e.message || String(e)); dispatch(setDisplayNameError(e.message || String(e)));
throw e; throw e;
}, },
}); });
@ -211,8 +202,8 @@ export const RestoreAccount = () => {
dispatch(setDisplayName('')); dispatch(setDisplayName(''));
dispatch(setProgress(0)); dispatch(setProgress(0));
setRecoveryPasswordError(''); dispatch(setRecoveryPasswordError(undefined));
setDisplayNameError(''); dispatch(setDisplayNameError(undefined));
}} }}
> >
<Flex <Flex
@ -276,7 +267,7 @@ export const RestoreAccount = () => {
placeholder={window.i18n('enterDisplayName')} placeholder={window.i18n('enterDisplayName')}
value={displayName} value={displayName}
onValueChanged={(_name: string) => { onValueChanged={(_name: string) => {
const name = sanitizeDisplayNameOrToast(_name, setDisplayNameError); const name = sanitizeDisplayNameOrToast(_name, setDisplayNameError, dispatch);
dispatch(setDisplayName(name)); dispatch(setDisplayName(name));
}} }}
onEnterPressed={recoverAndEnterDisplayName} onEnterPressed={recoverAndEnterDisplayName}

@ -1,16 +1,18 @@
import { AnyAction, Dispatch } from '@reduxjs/toolkit';
import { sanitizeSessionUsername } from '../../../session/utils/String'; import { sanitizeSessionUsername } from '../../../session/utils/String';
export function sanitizeDisplayNameOrToast( export function sanitizeDisplayNameOrToast(
displayName: string, displayName: string,
setDisplayNameError: (error: string | undefined) => void setDisplayNameError: (error: string | undefined) => AnyAction,
dispatch: Dispatch
) { ) {
try { try {
const sanitizedName = sanitizeSessionUsername(displayName); const sanitizedName = sanitizeSessionUsername(displayName);
const trimName = sanitizedName.trim(); const trimName = sanitizedName.trim();
setDisplayNameError(!trimName ? window.i18n('displayNameEmpty') : undefined); dispatch(setDisplayNameError(!trimName ? window.i18n('displayNameEmpty') : undefined));
return sanitizedName; return sanitizedName;
} catch (e) { } catch (e) {
setDisplayNameError(window.i18n('displayNameErrorDescriptionShorter')); dispatch(setDisplayNameError(window.i18n('displayNameErrorDescriptionShorter')));
return displayName; return displayName;
} }
} }

@ -111,7 +111,7 @@ async function retrieveNextMessages(
configHashesToBump: Array<string> | null configHashesToBump: Array<string> | null
): Promise<RetrieveMessagesResultsBatched> { ): Promise<RetrieveMessagesResultsBatched> {
if (namespaces.length !== lastHashes.length) { if (namespaces.length !== lastHashes.length) {
throw new Error('namespaces and last hashes does not match'); throw new Error('namespaces and last hashes do not match');
} }
const retrieveRequestsParams = await buildRetrieveRequest( const retrieveRequestsParams = await buildRetrieveRequest(

@ -35,8 +35,10 @@ export type OnboardDirection = 'backward' | 'forward';
export type OnboardingState = { export type OnboardingState = {
recoveryPassword: string; recoveryPassword: string;
recoveryPasswordError: string | undefined;
hexGeneratedPubKey: string; hexGeneratedPubKey: string;
displayName: string; displayName: string;
displayNameError: string | undefined;
progress: number; progress: number;
step: Onboarding; step: Onboarding;
accountCreationStep: AccountCreation; accountCreationStep: AccountCreation;
@ -46,8 +48,10 @@ export type OnboardingState = {
const initialState: OnboardingState = { const initialState: OnboardingState = {
recoveryPassword: '', recoveryPassword: '',
recoveryPasswordError: undefined,
hexGeneratedPubKey: '', hexGeneratedPubKey: '',
displayName: '', displayName: '',
displayNameError: undefined,
progress: 0, progress: 0,
step: Onboarding.Start, step: Onboarding.Start,
accountRestorationStep: AccountRestoration.RecoveryPassword, accountRestorationStep: AccountRestoration.RecoveryPassword,
@ -59,15 +63,24 @@ export const registrationSlice = createSlice({
name: 'registration', name: 'registration',
initialState, initialState,
reducers: { reducers: {
resetOnboardingState() {
return { ...initialState };
},
setRecoveryPassword(state, action: PayloadAction<string>) { setRecoveryPassword(state, action: PayloadAction<string>) {
return { ...state, recoveryPassword: action.payload }; return { ...state, recoveryPassword: action.payload };
}, },
setRecoveryPasswordError(state, action: PayloadAction<string | undefined>) {
return { ...state, recoveryPasswordError: action.payload };
},
setHexGeneratedPubKey(state, action: PayloadAction<string>) { setHexGeneratedPubKey(state, action: PayloadAction<string>) {
return { ...state, hexGeneratedPubKey: action.payload }; return { ...state, hexGeneratedPubKey: action.payload };
}, },
setDisplayName(state, action: PayloadAction<string>) { setDisplayName(state, action: PayloadAction<string>) {
return { ...state, displayName: action.payload }; return { ...state, displayName: action.payload };
}, },
setDisplayNameError(state, action: PayloadAction<string | undefined>) {
return { ...state, displayNameError: action.payload };
},
setProgress(state, action: PayloadAction<number>) { setProgress(state, action: PayloadAction<number>) {
return { ...state, progress: action.payload }; return { ...state, progress: action.payload };
}, },
@ -87,9 +100,12 @@ export const registrationSlice = createSlice({
}); });
export const { export const {
resetOnboardingState,
setRecoveryPassword, setRecoveryPassword,
setRecoveryPasswordError,
setHexGeneratedPubKey, setHexGeneratedPubKey,
setDisplayName, setDisplayName,
setDisplayNameError,
setProgress, setProgress,
setOnboardingStep, setOnboardingStep,
setAccountCreationStep, setAccountCreationStep,

@ -19,6 +19,11 @@ const getRecoveryPassword = createSelector(
(state: OnboardingState): string => state.recoveryPassword (state: OnboardingState): string => state.recoveryPassword
); );
const getRecoveryPasswordError = createSelector(
getRegistration,
(state: OnboardingState): string | undefined => state.recoveryPasswordError
);
const getHexGeneratedPubKey = createSelector( const getHexGeneratedPubKey = createSelector(
getRegistration, getRegistration,
(state: OnboardingState): string => state.hexGeneratedPubKey (state: OnboardingState): string => state.hexGeneratedPubKey
@ -29,6 +34,11 @@ const getDisplayName = createSelector(
(state: OnboardingState): string => state.displayName (state: OnboardingState): string => state.displayName
); );
const getDisplayNameError = createSelector(
getRegistration,
(state: OnboardingState): string | undefined => state.displayNameError
);
const getProgress = createSelector( const getProgress = createSelector(
getRegistration, getRegistration,
(state: OnboardingState): number => state.progress (state: OnboardingState): number => state.progress
@ -60,6 +70,10 @@ export const useRecoveryPassword = () => {
return useSelector(getRecoveryPassword); return useSelector(getRecoveryPassword);
}; };
export const useRecoveryPasswordError = () => {
return useSelector(getRecoveryPasswordError);
};
export const useOnboardHexGeneratedPubKey = () => { export const useOnboardHexGeneratedPubKey = () => {
return useSelector(getHexGeneratedPubKey); return useSelector(getHexGeneratedPubKey);
}; };
@ -68,6 +82,10 @@ export const useDisplayName = () => {
return useSelector(getDisplayName); return useSelector(getDisplayName);
}; };
export const useDisplayNameError = () => {
return useSelector(getDisplayNameError);
};
export const useProgress = () => { export const useProgress = () => {
return useSelector(getProgress); return useSelector(getProgress);
}; };

@ -8,7 +8,7 @@ import { SettingsKey } from '../data/settings-key';
import { ConversationTypeEnum } from '../models/conversationAttributes'; import { ConversationTypeEnum } from '../models/conversationAttributes';
import { SessionKeyPair } from '../receiver/keypairs'; import { SessionKeyPair } from '../receiver/keypairs';
import { getSwarmPollingInstance } from '../session/apis/snode_api'; import { getSwarmPollingInstance } from '../session/apis/snode_api';
import { NotEnoughWordsError, mnDecode, mnEncode } from '../session/crypto/mnemonic'; import { mnDecode, mnEncode } from '../session/crypto/mnemonic';
import { getOurPubKeyStrFromCache } from '../session/utils/User'; import { getOurPubKeyStrFromCache } from '../session/utils/User';
import { NotFoundError } from '../session/utils/errors'; import { NotFoundError } from '../session/utils/errors';
import { LibSessionUtil } from '../session/utils/libsession/libsession_utils'; import { LibSessionUtil } from '../session/utils/libsession/libsession_utils';
@ -104,8 +104,6 @@ export async function signInByLinkingDevice(
const pubKeyString = toHex(identityKeyPair.pubKey); const pubKeyString = toHex(identityKeyPair.pubKey);
// fetch configuration message to get the user's display name. // fetch configuration message to get the user's display name.
const displayName = await getSwarmPollingInstance().pollForOurDisplayName(); const displayName = await getSwarmPollingInstance().pollForOurDisplayName();
// TODO remove later
throw new NotEnoughWordsError('fml');
if (isEmpty(displayName)) { if (isEmpty(displayName)) {
throw new NotFoundError('Got a config message from network but without a displayName...'); throw new NotFoundError('Got a config message from network but without a displayName...');

Loading…
Cancel
Save