From 57b782c1b77b03668b273180b8318fb9455cfd10 Mon Sep 17 00:00:00 2001 From: Alex Ruzenhack Date: Thu, 12 Sep 2024 18:24:17 +0100 Subject: [PATCH] feat: add safe effect helper (#552) * feat: add safeEffect as a saga helper --- src/sagas/helpers.js | 20 ++++++++++++++++++++ src/sagas/nanoContract.js | 17 +++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/sagas/helpers.js b/src/sagas/helpers.js index b95350e65..63f7710be 100644 --- a/src/sagas/helpers.js +++ b/src/sagas/helpers.js @@ -353,3 +353,23 @@ export function* retryHandler(retryAction, dismissAction) { return retry != null; } + +/** + * A wrapper effect to catch unexpected error and provide a binding + * for the desired handling behavior. + * + * @param {Object} effect The targeted effect. + * @param {(error) => void} onError The error handling effect, + * which receives the error object as first argument. + * + * @returns An anonymous effect. + */ +export function safeEffect(effect, onError) { + return function* _safeEffect(payload) { + try { + yield call(effect, payload); + } catch (error) { + yield call(onError, error); + } + } +} diff --git a/src/sagas/nanoContract.js b/src/sagas/nanoContract.js index 46615029a..369fceced 100644 --- a/src/sagas/nanoContract.js +++ b/src/sagas/nanoContract.js @@ -36,7 +36,7 @@ import { import { logger } from '../logger'; import { NANO_CONTRACT_TX_HISTORY_SIZE } from '../constants'; import { consumeGenerator, getNanoContractFeatureToggle } from '../utils'; -import { getRegisteredNanoContracts } from './helpers'; +import { getRegisteredNanoContracts, safeEffect } from './helpers'; import { isWalletServiceEnabled } from './wallet'; const log = logger('nano-contract-saga'); @@ -158,6 +158,16 @@ export function* registerNanoContract({ payload }) { // emit action NANOCONTRACT_REGISTER_SUCCESS with feedback to user yield put(nanoContractRegisterSuccess({ entryKey: ncId, entryValue: nc, hasFeedback: true })); } +/** + * Effect invoked by safeEffect if an unexpected error occurs. + * + * @param {Object} error The error captured. + */ +function* registerNanoContractOnError(error) { + log.error('Unexpected error while registering Nano Contract.', error); + yield put(nanoContractRegisterFailure(failureMessage.nanoContractFailure)); + yield put(onExceptionCaptured(error, false)); +} /** * @typedef {Object} RawNcTxHistory @@ -440,7 +450,10 @@ export function* requestBlueprintInfo({ payload }) { export function* saga() { yield all([ debounce(500, [[types.START_WALLET_SUCCESS, types.NANOCONTRACT_INIT]], init), - takeEvery(types.NANOCONTRACT_REGISTER_REQUEST, registerNanoContract), + takeEvery( + types.NANOCONTRACT_REGISTER_REQUEST, + safeEffect(registerNanoContract, registerNanoContractOnError) + ), takeEvery(types.NANOCONTRACT_HISTORY_REQUEST, requestHistoryNanoContract), takeEvery(types.NANOCONTRACT_UNREGISTER_REQUEST, unregisterNanoContract), takeEvery(types.NANOCONTRACT_ADDRESS_CHANGE_REQUEST, requestNanoContractAddressChange),