当用户使用不正确的电子邮件和密码登录时,即使服务器返回400,我的客户端承诺的成功块仍会执行。
我正在使用Redux和React,所以我正在调用一个动作创建者,它使用axios调用HTTP请求。我需要帮助理解为什么我没有正确处理错误,因为即使我从服务器返回400个状态,我的应用程序的auth函数的其余部分如注册,注销等都表现相同的方式。
这是我从我的组件调用login的地方,成功块总是执行:
handleFormSubmit({
email, password
}) {
this.props.loginUser({
email, password
}).then(() => {
toastr.success("You are logged in!");
}).catch(() => {
toastr.warning("Could not log in");
})
}
这是动作创建者“loginUser”,当我从服务器返回400时,此功能的成功块不会运行:
export function loginUser({ email, password }) {
return function(dispatch) {
return axios.post(`/users/login`, {
email, password
})
.then(response => {
dispatch({
type: AUTH_USER
});
localStorage.setItem('token', response.headers['x-auth']);
browserHistory.push('/feature');
})
.catch(() => {
dispatch(authError('Incorrect email or password'));
});
}
}
这是路线'/ users / login'请注意400状态实际上确实返回:
app.post('/users/login', (req, res) => {
var body = _.pick(req.body, ['email', 'password']);
User.findByCredentials(body.email, body.password).then(user => {
return user.generateAuthToken().then(token => {
res.header('x-auth', token).send(user);
});
}).catch(e => {
res.status(400).send();
});
});
答案 0 :(得分:1)
问题出在loginUser函数的catch处理程序中。 如果你想在promise链中更远地捕获错误,你需要在catch块中抛出错误。
.catch(() => {
dispatch(authError('Incorrect email or password'));
throw Error('Incorrect email or password');
});
答案 1 :(得分:1)
你的问题是,你误解了catch
条款在承诺中的含义。
如果它只是一个拒绝处理程序那么你可以想到的方式:
.then(null, function(err) {
// handle the error
})
意思是只处理来自承诺链的最后一个未处理的错误,无论发生什么事情,你都可以继续链接它。
示例:
new Promise((resolve, reject) => {
setTimeout(() => reject(Error('After 1 sec')), 1000)
})
.catch((err) => {
console.log(`catch: ${err}`);
return 5;
})
.then((five) => {
// this chains because the error was handled before in the chain
console.log(`catch.then: ${five}`); // 5
})
.catch(() => {
console.log('No error happened between this error handler and previous so this is not logged');
});

要使错误从当前catch
传播到下一个错误处理程序,您可以返回被拒绝的Promise(或重新抛出错误),以使链跳过所有成功处理程序,直到下一次失败(或catch
)处理程序。
new Promise((resolve, reject) => {
setTimeout(() => reject(Error('After 1 sec')), 1000)
})
.catch((err) => {
// return a reject promise to propagate to the next error handler
return Promise.reject(err);
// can also `throw err;`
})
.then((nothing) => {
// this doesn't happen now
console.log(nothing);
})
.catch(console.error); // this logs the error

附注:如果您未在Promise链中提供拒绝处理程序(.then
中的第二个参数),则默认拒绝处理程序的行为基本上如下:
function defaultRejectionHandler(err) {
throw err;
}
这意味着它会重新抛出传递给它的错误,因此错误可以传播到您指定的下一个错误处理程序。