即使我 return 一个 404,我的承诺的成功块总是执行
The success block of my promise always executes even when I return a 404
当用户使用不正确的电子邮件和密码登录时,我的客户端承诺的成功块仍然执行,即使服务器 returned a 400。
我将 Redux 与 React 结合使用,因此我正在调用一个动作创建器,它使用 axios 调用 HTTP 请求。我需要帮助来理解为什么我没有正确处理错误,因为我的应用程序的其余身份验证功能(如注册、注销等)都以相同的方式运行,即使我从服务器 returning 400 状态也是如此。
这是我从我的组件调用登录的地方,成功块总是执行:
handleFormSubmit({
email, password
}) {
this.props.loginUser({
email, password
}).then(() => {
toastr.success("You are logged in!");
}).catch(() => {
toastr.warning("Could not log in");
})
}
这是动作创建者 "loginUser",当我 return 来自服务器的 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 状态实际上 return:
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();
});
});
问题出在您的 loginUser 函数的 catch 处理程序中。
如果您想在 promise 链的更深处捕获错误,则需要在 catch 块中抛出错误。
.catch(() => {
dispatch(authError('Incorrect email or password'));
throw Error('Incorrect email or password');
});
你的问题是你误解了承诺中的 catch
条款。
如果只是带有拒绝处理程序的 then,您可以这样想:
.then(null, function(err) {
// handle the error
})
意思是它只处理 promise 链中最后一个未处理的错误,无论发生什么,你都可以在它之后继续链接。
示例:
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
传播到下一个错误处理程序,您可以 return 一个被拒绝的 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;
}
这意味着它会重新抛出传递给它的任何错误,以便错误可以传播到您指定的下一个错误处理程序。
当用户使用不正确的电子邮件和密码登录时,我的客户端承诺的成功块仍然执行,即使服务器 returned a 400。
我将 Redux 与 React 结合使用,因此我正在调用一个动作创建器,它使用 axios 调用 HTTP 请求。我需要帮助来理解为什么我没有正确处理错误,因为我的应用程序的其余身份验证功能(如注册、注销等)都以相同的方式运行,即使我从服务器 returning 400 状态也是如此。
这是我从我的组件调用登录的地方,成功块总是执行:
handleFormSubmit({
email, password
}) {
this.props.loginUser({
email, password
}).then(() => {
toastr.success("You are logged in!");
}).catch(() => {
toastr.warning("Could not log in");
})
}
这是动作创建者 "loginUser",当我 return 来自服务器的 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 状态实际上 return:
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();
});
});
问题出在您的 loginUser 函数的 catch 处理程序中。 如果您想在 promise 链的更深处捕获错误,则需要在 catch 块中抛出错误。
.catch(() => {
dispatch(authError('Incorrect email or password'));
throw Error('Incorrect email or password');
});
你的问题是你误解了承诺中的 catch
条款。
如果只是带有拒绝处理程序的 then,您可以这样想:
.then(null, function(err) {
// handle the error
})
意思是它只处理 promise 链中最后一个未处理的错误,无论发生什么,你都可以在它之后继续链接。
示例:
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
传播到下一个错误处理程序,您可以 return 一个被拒绝的 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;
}
这意味着它会重新抛出传递给它的任何错误,以便错误可以传播到您指定的下一个错误处理程序。