Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/392.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cassandra/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用ES6承诺和书架FJ捕捉错误_Javascript_Node.js_Express_Es6 Promise_Bookshelf.js - Fatal编程技术网

Javascript 使用ES6承诺和书架FJ捕捉错误

Javascript 使用ES6承诺和书架FJ捕捉错误,javascript,node.js,express,es6-promise,bookshelf.js,Javascript,Node.js,Express,Es6 Promise,Bookshelf.js,我在ExpressJS应用程序中向Bookshelf用户模型添加了一个非常基本的登录方法,但是我无法捕捉到用户模型中的登录函数返回的拒绝承诺中的错误。我正在查看Bookshelf在的文档中的示例登录,但该示例使用Bluebird,而我正在尝试对内置ES6承诺执行相同的操作 用户模型中的我的登录方法: userModel.js 实现登录并从书架User模型调用User.login的控制器操作: usersAuthController.js 我的意图是,当Bookshelf的方法无法找到具有给定电子

我在ExpressJS应用程序中向Bookshelf用户模型添加了一个非常基本的登录方法,但是我无法捕捉到用户模型中的登录函数返回的拒绝承诺中的错误。我正在查看Bookshelf在的文档中的示例登录,但该示例使用Bluebird,而我正在尝试对内置ES6承诺执行相同的操作

用户模型中的我的登录方法:

userModel.js

实现登录并从书架
User
模型调用
User.login
的控制器操作:

usersAuthController.js

我的意图是,当Bookshelf的方法无法找到具有给定电子邮件的用户时,
login()
可以返回一个被拒绝的承诺。在这种情况下,
.catch(User.NotFoundError…
(catch#1)行应该捕获它并返回404。当
bcrypt
确定传递给
login()
的密码与用户密码不匹配时,我还打算
login()
返回被拒绝的承诺,在这种情况下
用户下方的“catch all”(catch#2)。NotFoundError
catch语句应返回401

如果我输入了不正确的密码,上述代码中的
logUserIn()
控制器操作将捕获#2,错误消息为
{error:“无法设置未定义的属性'message'}
,而不是消息
'password not match!'我在
login()
中拒绝的消息。如果我输入了一封不存在的电子邮件,则永远不会发送响应,并且控制台中会抛出错误
未处理的拒绝CustomError:EmptyResponse
。只有有效的输入才有效

尝试修复:而是直接在模型中捕获
用户.NotFoundError

我将catch#1移动到用户模型中,以便登录方法现在看起来像:

userModel.js

通过这种方式,我可以正确捕获两个错误(不正确的密码和不存在的电子邮件),但通过这种方式,我无法在控制器中指定状态代码。如果找不到具有给定电子邮件的用户,则应返回404,但如果密码不正确,则应返回401,但这两个错误都会转到控制器操作(始终返回401)中的catch all(catch#2)

为了解决这个问题,在
User
模型中,我可以执行
.catch(User.NotFoundError,()=>reject({name:'NotFoundError',message:'User not found!'}))
并且在控制器操作中,我可以检查
const statusCode=err.name=='NotFoundError'得到的错误类型?404:401
但这看起来真的很混乱,没有抓住这些
.catch
语句的要点


是否有方法从模型的登录方法中捕获
用户.NotFoundError
,以及
登录用户
中的所有其他错误?为什么我最初的设置不起作用,在usersAuthController.js中既有
catch
语句,又有
无法设置未定义的属性“message”和
CustomError:EmptyResponse
错误意味着什么(这是否与Bookshelf的Bluebird承诺与内置ES6承诺的混淆有关)?处理这一问题的最佳方法是什么?

在最初的实现中,您不会传播任何可能由
User.fetch()
引起的拒绝。另外,因为
User.fetch()
已经返回了一个承诺,用新承诺包装它有点反模式(尽管您仍然需要用承诺包装
bcrypt.compare()
,因为这只适用于回调)

试试这个:

function login(email, password) {
  return User .where('email', email)
              .fetch({ require: true })
              .then(user => {
                return new Promise((resolve, reject) => {
                  bcrypt.compare(password, user.get('password'), (err, matched) => {
                    if (err)      return reject(err);
                    if (!matched) return reject(new Error('Password didn\'t match!'));
                    resolve(user);
                  });
                })
              });
}

在最初的实现中,您不会传播任何可能由
User.fetch()
引起的拒绝。另外,因为
User.fetch()
已经返回了一个承诺,用新的承诺包装它有点反模式(尽管您仍然需要包装
bcrypt.compare()
带有承诺,因为这只适用于回调)

试试这个:

function login(email, password) {
  return User .where('email', email)
              .fetch({ require: true })
              .then(user => {
                return new Promise((resolve, reject) => {
                  bcrypt.compare(password, user.get('password'), (err, matched) => {
                    if (err)      return reject(err);
                    if (!matched) return reject(new Error('Password didn\'t match!'));
                    resolve(user);
                  });
                })
              });
}

谢谢!我只是想澄清一下,通常我应该在什么时候把东西包装在承诺中(如果我得到了这一点,就是在
中返回承诺的意义。然后
是为了我可以链接
。然后
s)?@satray如果某个东西已经返回了一个承诺,你就不必包装它。在这种情况下,因为
bcrypt.compare
不返回承诺,它会被包装(但“尽可能晚”)。即使你处理
.then()
.catch(),返回承诺(和承诺链)总是一件好事
已经有了。谢谢!我只是想澄清一下,通常我应该在什么时候把东西包装在承诺中(如果我得到了这个,就是在
中返回承诺的目的。
就是为了让我可以链接
。然后
s)?@satray如果某个东西已经返回了一个承诺,你就不必包装它。在这种情况下,因为
bcrypt.compare
不返回承诺,它会被包装(但“尽可能晚”)。即使你处理
.then()
.catch(),返回承诺(和承诺链)总是一件好事
已经。避免!您应该只在
login
函数中提示
bcrypt.compare
。避免!您应该只在
login
函数中提示
bcrypt.compare
function login(email, password) {
  return new Promise((resolve, reject) => {
    User.where('email', email)
      .fetch({ require: true })
      .then(user => {
        bcrypt.compare(password, user.get('password'), (err, matched) => {
          if (!matched) return reject(new Error('Password didn\'t match!'));
          resolve(user);
        });
      })
      .catch(User.NotFoundError, () => reject({ error: 'User not found!' }));
  });
function login(email, password) {
  return User .where('email', email)
              .fetch({ require: true })
              .then(user => {
                return new Promise((resolve, reject) => {
                  bcrypt.compare(password, user.get('password'), (err, matched) => {
                    if (err)      return reject(err);
                    if (!matched) return reject(new Error('Password didn\'t match!'));
                    resolve(user);
                  });
                })
              });
}