Commit 90faeb9a authored by Peter Van der Beken's avatar Peter Van der Beken
Browse files

Bug 1788969 - Reject async iterable result promises on error instead of throwing. r=edgar

parent 74d51ab6
Loading
Loading
Loading
Loading
+15 −12
Original line number Diff line number Diff line
@@ -67,26 +67,28 @@ void KeyAndValueReturn(JSContext* aCx, JS::Handle<JS::Value> aKey,
  aResult.set(&dictValue.toObject());
}

void ResolvePromiseForFinished(JSContext* aCx, Promise* aPromise,
                               ErrorResult& aRv) {
void ResolvePromiseForFinished(JSContext* aCx, Promise* aPromise) {
  MOZ_ASSERT(aPromise);

  ErrorResult error;
  JS::Rooted<JSObject*> dict(aCx);
  DictReturn(aCx, &dict, true, JS::UndefinedHandleValue, aRv);
  if (aRv.Failed()) {
  DictReturn(aCx, &dict, true, JS::UndefinedHandleValue, error);
  if (error.Failed()) {
    aPromise->MaybeReject(std::move(error));
    return;
  }
  aPromise->MaybeResolve(dict);
}

void ResolvePromiseWithKeyOrValue(JSContext* aCx, Promise* aPromise,
                                  JS::Handle<JS::Value> aKeyOrValue,
                                  ErrorResult& aRv) {
                                  JS::Handle<JS::Value> aKeyOrValue) {
  MOZ_ASSERT(aPromise);

  ErrorResult error;
  JS::Rooted<JSObject*> dict(aCx);
  DictReturn(aCx, &dict, false, aKeyOrValue, aRv);
  if (aRv.Failed()) {
  DictReturn(aCx, &dict, false, aKeyOrValue, error);
  if (error.Failed()) {
    aPromise->MaybeReject(std::move(error));
    return;
  }
  aPromise->MaybeResolve(dict);
@@ -94,13 +96,14 @@ void ResolvePromiseWithKeyOrValue(JSContext* aCx, Promise* aPromise,

void ResolvePromiseWithKeyAndValue(JSContext* aCx, Promise* aPromise,
                                   JS::Handle<JS::Value> aKey,
                                   JS::Handle<JS::Value> aValue,
                                   ErrorResult& aRv) {
                                   JS::Handle<JS::Value> aValue) {
  MOZ_ASSERT(aPromise);

  ErrorResult error;
  JS::Rooted<JSObject*> dict(aCx);
  KeyAndValueReturn(aCx, aKey, aValue, &dict, aRv);
  if (aRv.Failed()) {
  KeyAndValueReturn(aCx, aKey, aValue, &dict, error);
  if (error.Failed()) {
    aPromise->MaybeReject(std::move(error));
    return;
  }
  aPromise->MaybeResolve(dict);
+3 −6
Original line number Diff line number Diff line
@@ -47,17 +47,14 @@ void KeyAndValueReturn(JSContext* aCx, JS::Handle<JS::Value> aKey,
                       JS::Handle<JS::Value> aValue,
                       JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv);

void ResolvePromiseForFinished(JSContext* aCx, Promise* aPromise,
                               ErrorResult& aRv);
void ResolvePromiseForFinished(JSContext* aCx, Promise* aPromise);

void ResolvePromiseWithKeyOrValue(JSContext* aCx, Promise* aPromise,
                                  JS::Handle<JS::Value> aKeyOrValue,
                                  ErrorResult& aRv);
                                  JS::Handle<JS::Value> aKeyOrValue);

void ResolvePromiseWithKeyAndValue(JSContext* aCx, Promise* aPromise,
                                   JS::Handle<JS::Value> aKey,
                                   JS::Handle<JS::Value> aValue,
                                   ErrorResult& aRv);
                                   JS::Handle<JS::Value> aValue);
}  // namespace iterator_utils

class IterableIteratorBase : public nsISupports {
+6 −7
Original line number Diff line number Diff line
@@ -90,34 +90,33 @@ void TestInterfaceAsyncIterableDouble::ResolvePromise(Iterator* aIterator) {

  AutoJSAPI jsapi;
  if (NS_WARN_IF(!jsapi.Init(mParent))) {
    data->mPromise->MaybeRejectWithInvalidStateError(
        "Couldn't get the global.");
    return;
  }
  JSContext* cx = jsapi.cx();
  ErrorResult rv;

  // Test data: ['a', 'b'], ['c', 'd'], ['e', 'f']
  uint32_t idx = data->mIndex;
  if (idx >= mValues.Length()) {
    iterator_utils::ResolvePromiseForFinished(cx, data->mPromise, rv);
    iterator_utils::ResolvePromiseForFinished(cx, data->mPromise);
  } else {
    JS::Rooted<JS::Value> key(cx);
    JS::Rooted<JS::Value> value(cx);
    switch (aIterator->GetIteratorType()) {
      case IterableIteratorBase::IteratorType::Keys:
        Unused << ToJSValue(cx, mValues[idx].first, &key);
        iterator_utils::ResolvePromiseWithKeyOrValue(cx, data->mPromise, key,
                                                     rv);
        iterator_utils::ResolvePromiseWithKeyOrValue(cx, data->mPromise, key);
        break;
      case IterableIteratorBase::IteratorType::Values:
        Unused << ToJSValue(cx, mValues[idx].second, &value);
        iterator_utils::ResolvePromiseWithKeyOrValue(cx, data->mPromise, value,
                                                     rv);
        iterator_utils::ResolvePromiseWithKeyOrValue(cx, data->mPromise, value);
        break;
      case IterableIteratorBase::IteratorType::Entries:
        Unused << ToJSValue(cx, mValues[idx].first, &key);
        Unused << ToJSValue(cx, mValues[idx].second, &value);
        iterator_utils::ResolvePromiseWithKeyAndValue(cx, data->mPromise, key,
                                                      value, rv);
                                                      value);
        break;
    }

+6 −7
Original line number Diff line number Diff line
@@ -97,35 +97,34 @@ void TestInterfaceAsyncIterableDoubleUnion::ResolvePromise(

  AutoJSAPI jsapi;
  if (NS_WARN_IF(!jsapi.Init(mParent))) {
    data->mPromise->MaybeRejectWithInvalidStateError(
        "Couldn't get the global.");
    return;
  }
  JSContext* cx = jsapi.cx();
  ErrorResult rv;

  // Test data:
  // [long, 1], [string, "a"]
  uint32_t idx = data->mIndex;
  if (idx >= mValues.Length()) {
    iterator_utils::ResolvePromiseForFinished(cx, data->mPromise, rv);
    iterator_utils::ResolvePromiseForFinished(cx, data->mPromise);
  } else {
    JS::Rooted<JS::Value> key(cx);
    JS::Rooted<JS::Value> value(cx);
    switch (aIterator->GetIteratorType()) {
      case IterableIteratorBase::IteratorType::Keys:
        Unused << ToJSValue(cx, mValues[idx].first, &key);
        iterator_utils::ResolvePromiseWithKeyOrValue(cx, data->mPromise, key,
                                                     rv);
        iterator_utils::ResolvePromiseWithKeyOrValue(cx, data->mPromise, key);
        break;
      case IterableIteratorBase::IteratorType::Values:
        Unused << ToJSValue(cx, mValues[idx].second, &value);
        iterator_utils::ResolvePromiseWithKeyOrValue(cx, data->mPromise, value,
                                                     rv);
        iterator_utils::ResolvePromiseWithKeyOrValue(cx, data->mPromise, value);
        break;
      case IterableIteratorBase::IteratorType::Entries:
        Unused << ToJSValue(cx, mValues[idx].first, &key);
        Unused << ToJSValue(cx, mValues[idx].second, &value);
        iterator_utils::ResolvePromiseWithKeyAndValue(cx, data->mPromise, key,
                                                      value, rv);
                                                      value);
        break;
    }

+5 −4
Original line number Diff line number Diff line
@@ -98,18 +98,19 @@ void TestInterfaceAsyncIterableSingle::ResolvePromise(
    IterableIteratorBase* aIterator, IteratorData* aData) {
  AutoJSAPI jsapi;
  if (NS_WARN_IF(!jsapi.Init(mParent))) {
    aData->mPromise->MaybeRejectWithInvalidStateError(
        "Couldn't get the global.");
    return;
  }
  JSContext* cx = jsapi.cx();
  ErrorResult rv;

  if (aData->mIndex >= 10) {
    iterator_utils::ResolvePromiseForFinished(cx, aData->mPromise, rv);
    iterator_utils::ResolvePromiseForFinished(cx, aData->mPromise);
  } else {
    JS::Rooted<JS::Value> value(cx);
    Unused << ToJSValue(
        cx, (int32_t)(aData->mIndex * 9 % 7 * aData->mMultiplier), &value);
    iterator_utils::ResolvePromiseWithKeyOrValue(cx, aData->mPromise, value,
                                                 rv);
    iterator_utils::ResolvePromiseWithKeyOrValue(cx, aData->mPromise, value);

    aData->mIndex++;
  }
Loading