перехват исключений при ожидании обещания в nodejs

1

Я пишу библиотеку в nodejs, которая обертывает другую библиотеку. мой код выглядит примерно так:

function wrapper(functionToWrap) {
    return function(param1, param2) {
        try {
             return functionToWrap(param1, param2);
        } catch(err) {
            console.log(err);
            throw err;
        } finally {
            finalizeWrapping();
        }
    }
}

проблема в том, что моя функция finalizeWrapping - это функция, которая ждет обещаний, которые я собираю (путем размещения некоторых перехватов перед вызовом функцииToWrap для некоторых асинхронных apis, которые она использует) для разрешения и только затем действует примерно так:

function finalizeWrapping() {
    Promise.all(pendingPromises).then(function(values) {
        //finalize the wrapping
        console.log('all promises fulfilled!');
    });
}

проблема заключается в том, что ошибка вызывается, и узел выходит (эта ошибка не должна обрабатываться, поскольку обернутая функция не обрабатывает ее) до того, как все обещания будут разрешены, а затем будет выполнен блок.

мой вопрос: есть ли что-нибудь, что я могу сделать для того, чтобы обойти это, что означает, что он должен правильно выполнить ошибку пользователю и закончить выполнение тогдашнего блока, или мне нужно изменить способ привязки apis к синхронному и не использовать обещание?

Спасибо заранее всем помощникам :)

EDIT: попытка сделать мой вопрос яснее - functionToWrap - это не моя функция, это функция другой библиотеки (и она может измениться - это означает, что мой код сможет обернуть как можно больше функций). этой функции разрешено использовать async apis (который я могу попробовать для monkeypatch), и в основном он должен иметь как можно меньше ограничений - я хочу, чтобы пользователь мог написать любую функцию, и я мог ее обернуть.

  • 0
    поделиться кодом functionToWrap ()
  • 0
    Похоже, вам нужно, чтобы анонимная функция, которую вы возвращаете в wrapper возвращала обещание (которое разрешается в finally ), или измените метод finaliseWrapping на синхронный (но я предполагаю, что это невозможно, иначе вы, вероятно, имели бы сделал это! :)
Показать ещё 2 комментария
Теги:
error-handling
promise
throw

1 ответ

0

Не уверен, что следующее может помочь, у вас может не хватить репутации для комментариев, хотя я думаю, что вы можете прокомментировать свой собственный вопрос, и он отвечает.

const wrapper = functionToWrap => 
  function() {
      //special type to indicate failed call to functionToWrap
      const Fail = function(reason){this.reason=reason;};
      //does not matter how many argument. Assuming functionToWrap
      //  does not rely on "this". If it does then also pass the 
      //  object that functionToWrap is on and replace null with that object
      return Promise.resolve(Array.from(arguments))
      .then(
        //if functionToWrap is on an object pass it to wrapper
        // and replace null with that object
        args=>functionToWrap.apply(null,args)
      )
      .catch(
        //if functionToWrap throws an error or rejects we will catch it here
        //  and resolve with a special Fail type value
        err=>{
          console.log(err);
          return new Fail(err)          
        }
      ).then(
        //since promise cannot fail (its rejection is caught and resolves with Fail)
        //  this will always be called
        //finalize should return Promise.all... and maybe not use a shared
        //  variable called pendingPromises, global shared mutable variables in async 
        //  functions is asking for trouble
        result=>finalizeWrapping().then(
          ()=>
            //if functionToWrap rejected or thew the result will be a Fail type
            (result && result.constructor === Fail)
              ? Promise.reject(result.reason)//reject with the original error
              : result//resolve with the functionToWrap result
        )
      );
  }
  • 0
    эй, спасибо за отличный ответ! небольшой вопрос: будет ли перенос функции теперь изменять возвращаемое значение functionToWrap на обещание?
  • 0
    @GalBashan Да, я разместил комментарий с вопросом по вашему вопросу. Обернутая функция будет вызывать finalizeWrapping и если функция, вызывающая обернутую функцию, должна знать, finalizeWrapping ли finalizeWrapping и когда она завершена, вы должны вернуть обещание, потому что finalizeWrapping является асинхронным.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню