Try / Catch не перехватывает с помощью функции asyn c используя await - PullRequest
0 голосов
/ 06 января 2020

Когда у меня есть этот код:


export default async ({
  inputs,
  stdin = process.stdin,
  timeoutBetweenInputs = DEFAULT_TIMEOUT_BETWEEN_INPUTS
}: ISendInputsToCli): Promise<void> => {
  // go through each input, waiting for the last timeout to
  // resolve
  // write the input to stdin
  return inputs.reduce(
    (previousPromise, input) =>
      new Promise(async (resolve, reject) => {
        await previousPromise;
        let inputString;

        if (typeof input !== "string") {
          timeoutBetweenInputs = input.timeoutBeforeInput;
          inputString = input.input;
        } else {
          inputString = input;
        }

        setTimeout(() => {
          try {
            stdin.write(inputString);
          } catch (e) {
            throw new Error(
              `Unable to send input "${inputString}" to the cli. Please check to make sure your script didn't exit early.`
            );
            inputs.splice(0, inputs.length);
          }
          resolve();
        }, timeoutBetweenInputs);
      }),
    Promise.resolve()
  );
};

try {
      await sendInputsToCLI({
        inputs,
        stdin: proc.stdin,
        timeoutBetweenInputs
      });
    } catch (e) {
      console.log("error here");
    }

Приложение не улавливает ошибку:

 " to the cli. Please check to make sure your script didn't exit ea
rly.

      52 |             stdin.write(inputString);
      53 |           } catch (e) {
    > 54 |             throw new Error(
         |                   ^
      55 |               `Unable to send input "${inputString}" to the cli. Please check to make sure your script didn't exit early.`
      56 |             );
      57 |             inputs.splice(0, inputs.length);

      at Timeout._onTimeout (index.ts:54:19)

1 Ответ

0 голосов
/ 06 января 2020

Когда вы throw в обработчике catch здесь:

    setTimeout(() => {
      try {
        stdin.write(inputString);
      } catch (e) {
        throw new Error(
          `Unable to send input "${inputString}" to the cli. Please check to make sure your script didn't exit early.`
        );
        inputs.splice(0, inputs.length);
      }

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

Исключения являются сложными распространяться обратно через простые асинхронные обратные вызовы. На самом деле, вы не можете сделать это так, как вы это сделали. Если бы это был мой код, я бы контролировал свой поток асинхронных операций, используя только функции, которые возвращают обещания. Когда у вас есть асинхронная операция, которая использует простой обратный вызов, а не обещание, вы «обещаете» его с помощью небольшой что-то вроде util.promisify() или специальной маленькой оболочки обещаний, а затем вы можете выбросить в свое сердце контент, и он автоматически распространится вверх на более высокие уровни или обратно к вызывающей стороне в качестве отклоненного обещания.

К вашему сведению, также неясно, почему у вас есть строка кода:

inputs.splice(0, inputs.length);

в этом фрагменте, поскольку он никогда не может быть выполнен как это после throw.

...