Получение UnhandledPromiseRejectionWarning даже при отлове отказа - PullRequest
0 голосов
/ 25 марта 2020

У меня в основном есть проходной тест, который пройдет, только если обещание было отклонено. В то же время Node сообщает мне, что я не поймал отклоненное обещание ... Это вывод из прохождения теста, завершенный выводом отладки, который, я думаю, указывает на проблему basi c (предупреждение показывается после теста завершен).

$ DEBUG=run-esm,test.js mocha test.js 

  run-esm module
  run-esm listening to port 45765 +0ms
  run-esm received text on browser console: "bundle-check-FAIL Uncaught Error: Something wrong,http://localhost:45765/,13,41,Error: Something wrong" +185ms
  run-esm failure detected +0ms
  run-esm die called with reason: Uncaught Error: Something wrong,http://localhost:45765/,13,41,Error: Something wrong +0ms
  test.js p failed as expected Uncaught Error: Something wrong,http://localhost:42283/,13,41,Error: Something wrong +0ms
    ✓ should reject the returned promise on uncaught errors (187ms)
(node:1381) UnhandledPromiseRejectionWarning: Uncaught Error: Something wrong,http://localhost:45765/,13,41,Error: Something wrong
(node:1381) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:1381) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
  run-esm pageerror [Error: Error: Something wrong
    at http://localhost:45765/:13:41] +1ms
  run-esm die called with reason: [Error: Error: Something wrong
    at http://localhost:45765/:13:41] +1ms
  run-esm end of puppeteer script +0ms
  run-esm server has closed +11ms

Вывод основан на этом тесте :

it("should reject the returned promise on uncaught errors", async () => {
  const p = runEsm({
    bundlePath: `${__dirname}/example-module.mjs`,
    testScriptSource: `
          import myModule from "./example-module.mjs";
          if(myModule() != 142) throw new Error("Something wrong"); // will throw
          `,
  });

  await p
    .then(
      () => {
        throw new Error("Should have failed");
      },
      (err) => {
        debug("p failed as expected", err);
      }
    )

, который вызывает следующую функцию , которая в основном возвращает Обещание, которое будет разрешено или отклонено обратным вызовом.

async function run({
  bundlePath,
  testScriptSource,
  puppeteerExecutablePath,
  puppeteerArgs,
}) {
  const port = await getPort();
  assert(port);
  assert(testScriptSource);
  assert(bundlePath);

  debug("listening to port", port);

  const app = createApp({ bundlePath, testScriptSource });
  const p = new Promise((resolve, reject) => {
    app.listen(
      port,
      evaluatePageContent({
        resolve,
        reject,
        port,
        puppeteerArgs,
        puppeteerExecutablePath,
      })
    );
  });

  p.catch((err) => {
    app.close(() => debug("server has closed"));
  });

  p.then(() => app.close());

  return p;

Основная работа выполняется функцией обратного вызова.

const evaluatePageContent = ({
  resolve,
  reject,
  port,
  puppeteerArgs,
  puppeteerExecutablePath,
}) =>
  async function () {
    assert(port);

    const timerRef = setTimeout(
      () => die("No result within timeout."),
      TIMEOUT
    );
    const browser = await puppeteer.launch({
      args: puppeteerArgs,
      // allow overriding chrome path
      executablePath: puppeteerExecutablePath,
    });
    const page = await browser.newPage();
    const cancelTimer = () => clearTimeout(timerRef);
    let dead = false;

    async function die(reason) {
      debug("die called with reason:", reason);
      if (dead) return;
      dead = true;

      cancelTimer();
      reject(reason);
    } 
    ...

Важным моментом, который следует здесь отметить, является функция die(), единственная вещь, которая reject() s Обещание. Следовательно, это источник этой ошибки. То, что я не понимаю, почему это считается необработанным. Обещание, которое он отвергает, прослушивается в тесте и обрабатывается обработчиком .catch(). Также к нему подключаются несколько других обработчиков. Как будто где-то есть побочный эффект, которым я не занимаюсь ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...