Add try/catch protection for statePlugin interfaces

This commit is contained in:
Kyle Shockey
2018-01-03 13:56:29 -06:00
parent b749ea737d
commit c601f9b0ca
2 changed files with 323 additions and 116 deletions

View File

@@ -176,7 +176,7 @@ export default class Store {
if(!isFn(newAction)) {
throw new TypeError("wrapActions needs to return a function that returns a new function (ie the wrapped action)")
}
return newAction
return wrapWithTryCatch(newAction)
}, action || Function.prototype)
})
}
@@ -256,11 +256,11 @@ export default class Store {
return objMap(obj, (fn) => {
return (...args) => {
let res = fn.apply(null, [getNestedState(), ...args])
let res = wrapWithTryCatch(fn).apply(null, [getNestedState(), ...args])
// If a selector returns a function, give it the system - for advanced usage
if(typeof(res) === "function")
res = res(getSystem())
res = wrapWithTryCatch(res)(getSystem())
return res
}
@@ -331,7 +331,7 @@ function callAfterLoad(plugins, system, { hasLoaded } = {}) {
if(isObject(plugins) && !isArray(plugins)) {
if(typeof plugins.afterLoad === "function") {
calledSomething = true
plugins.afterLoad.call(this, system)
wrapWithTryCatch(plugins.afterLoad).call(this, system)
}
}
@@ -436,14 +436,36 @@ function makeReducer(reducerObj) {
if(!reducerObj)
return state
let redFn = reducerObj[action.type]
let redFn = (reducerObj[action.type])
if(redFn) {
return redFn(state, action)
const res = wrapWithTryCatch(redFn)(state, action)
// If the try/catch wrapper kicks in, we'll get null back...
// in that case, we want to avoid making any changes to state
return res === null ? state : res
}
return state
}
}
function wrapWithTryCatch(fn, {
logErrors = true
} = {}) {
if(typeof fn !== "function") {
return fn
}
return function(...args) {
try {
return fn.call(this, ...args)
} catch(e) {
if(logErrors) {
console.error(e)
}
return null
}
}
}
function configureStore(rootReducer, initialState, getSystem) {
const store = createStoreWithMiddleware(rootReducer, initialState, getSystem)