Kon*_*kov 14 javascript error-handling redux
想象一下处理表单提交的情况,它可以返回不同的错误:400,401,500.当返回400时,我想在表单顶部显示一条消息(覆盖默认行为).对于其他(未处理的)错误代码,应调用默认(全局)错误处理程序(显示通知toast).只是不想为每个动作复制此代码
我使用redux-thunk中间件调度异步操作
// Pseudo code
const action = (dispatch) => {
const onSuccess = (result) => dispatch({type: 'OPERATION_SUCCESS', payload: result});
const onError = (error) => dispatch({type: 'OPERATION_ERROR', error: true, payload: error});
return promise.then(onSuccess, onError);
};
dispatch(action);
Run Code Online (Sandbox Code Playgroud)
我可以创建一个reducer来处理所有{error:true}动作并显示一些弹出通知(可能没有使用redux状态,直接调用一些toast.show()方法)但是如何确定这个特殊错误是否已被某些人处理过其他减速机?
Dan*_*mov 20
当动作到达减速器时,这是事实.它反映了已经发生的事情.在问"其他减速器是否处理了这个动作?"是没有意义的,因为减速器应该是被动的,一般来说,不知道彼此的存在.在可能的情况下,他们应该努力保持独立.
没有一种"真正"的方法可以实现你想要的东西,但是由于你已经使用了将error属性视为全局错误来处理任何对象的约定,你不妨引入另一种约定,例如"如果动作有一个suppressGlobalErrorNotification标志,那么全局减误器不应该关心它".
// utilities
function checkStatus(response) {
if (response.status >= 200 && response.status < 300) {
return response
} else {
const error = new Error(response.statusText)
error.response = response
throw error
}
}
function parseJSON(response) {
return response.json()
}
export function post(url, data) {
const options = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
}
return fetch(url, options)
.then(checkStatus)
.then(parseJSON)
}
// action creators
import { post } from './utils'
export function submitForm(data) {
return dispatch => post('/myform', data).then(
response => dispatch({
type: 'SUBMIT_FORM_SUCCESS',
payload: response
}),
error => dispatch({
type: 'SUBMIT_FORM_FAILURE',
error: error,
suppressGlobalErrorNotification: (
error.response &&
error.response.status === 400
)
})
)
}
// reducers
export function error(state = null, action) {
if (!action.error || action.suppressGlobalErrorNotification) {
return state
}
if (action.type === 'RESET_ERROR') {
return null
}
return action.error
}
export function form(state = {}, action) {
switch (action.type) {
case 'SUBMIT_FORM_FAILURE':
return Object.assign({}, state, { isFormError: true })
// ...
default:
return state
}
}
Run Code Online (Sandbox Code Playgroud)