【问题标题】:Promise.reject in .then() returning undefined.then() 中的 Promise.reject 返回未定义
【发布时间】:2019-04-23 14:35:17
【问题描述】:

我目前有一个带有构造函数和两个方法的 ES6 类。我有点困惑为什么在.then() 中使用Promise.reject(ex) 会解决未定义的问题。如果有人不介意解释我做错了什么,那将不胜感激。

我有一个名为getYaml() 的方法,其中包含以下内容:

_getYaml(recordId) {
  return new Promise((resolve, reject) => {
    fs.readFile(this.workingDir + '/' + recordId + '.yaml', 'utf8', function(err, data) {
      if (err) reject(err)
      resolve(data)
    })
  })
}

然后我有另一种方法称为getCompDoc,它利用了另一种方法,如下所示:

getCompDoc(recordId) {
  return this._getYaml(recordId).then(data => {

    let yaml = data

    let yamlObj
    try {
      yamlObj = YAML.safeLoad(yaml)
    } catch (ex) {
      ex.message = `Failure to parse yaml. Error: ${ex.message}`
      logger.error(ex.message, {}, ex)
      return Promise.reject(ex)
    }

    let compDoc = {
      // ...
    }

    return compDoc

  }).catch(err => {
    logger.error(err, {}, err)
  })
}

然后我有一个测试来检查 YAML 解析错误是否被捕获,然后一个 Promise 被拒绝,看起来像这样:

describe('error cases', () => {
  const fakeRecordId = 'SomeYaml'
  beforeEach(() => {
    sinon.stub(myClass, '_getYaml').returns(Promise.resolve('{{&^%}egrinv&alidgj%^%^&$£@£@£}'))
  })

  afterEach(() => {
    myClass._getYaml.restore()
  })

  it('Error parsing yaml, rejects with error', () => {
    return expect(myClass.getCompDoc(fakeRecordId)).to.be.rejected.then(response => {
      expect(response.message).to.match(/Failure to parse yaml. Error: /)
    })
  })
})

测试输出:

AssertionError: expected promise to be rejected but it was fulfilled with undefined

如果我只是返回getCompDoc 方法中引发的异常,我会按预期收到错误,但是一旦我使用Promise.reject,它就会以未定义的形式解决。

我正在考虑将 getCompDoc 包装在 return new Promise() 中,但是我不确定这是否是 Promise 构造函数反模式的示例。理想情况下,我想拒绝这个,而不是直接返回错误,因为这样我就可以断言该方法被拒绝并且没有实现。

【问题讨论】:

  • 我不知道为什么你不允许异常落入你的捕获中,而不是包装在 getCompDoc 中的 try/catch 中,例如const yamlObj = await YAML.safeLoad(yaml)?
  • 抛出 ex 给我同样的断言错误
  • }).catch(err => { logger.error(err, {}, err) }) 捕获所有错误,我猜你需要重新抛出它。

标签: javascript promise mocha.js sinon sinon-chai


【解决方案1】:

您在catch 子句中“吞下”了getCompDoc 中的错误。具体来说,这是一个简化的 sn-p 代表您的代码:

let getYamlPromise = Promise.reject('REJECTED!');

let getCompDocPromise = getYamlPromise
    .then(data => console.log('getYamlPromise', data))
    .catch(error => console.error('getYamlPromise', error));

getCompDocPromise
    .then(a => console.log('getCompDocPromise RESOLVED', a))
    .catch(a => console.log('getCompDocPromise REJECTED', a));

如您所见,getCompDocPromise 使用 undefined 解析。如果您想传播错误,您的 catch 子句将不得不抛出一个新错误或返回一个被拒绝的承诺:

let getYamlPromise = Promise.reject('REJECTED!');

let getCompDocPromise = getYamlPromise
    .then(data => console.log('getYamlPromise', data))
    .catch(error => {
      console.error('getYamlPromise', error);
      return Promise.reject(error);
    });

getCompDocPromise
    .then(a => console.log('getCompDocPromise RESOLVED', a))
    .catch(a => console.log('getCompDocPromise REJECTED', a));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-27
    • 1970-01-01
    • 2016-07-11
    • 2023-03-29
    • 1970-01-01
    • 2016-03-21
    • 1970-01-01
    相关资源
    最近更新 更多