Получение исключения всякий раз, когда обещание отклоняется в приложении NodeJS, что вызывает перезапуск приложения - PullRequest
0 голосов
/ 04 октября 2019

Я смотрю на ошибку, возникающую в нашем производственном приложении. Это приложение на основе NodeJS, и в нем написаны API REST. Мы столкнулись с проблемой с одним из API, скажем /data/.

Так что, когда приходит запрос, мы получаем информацию для этих данных из 2 разных источников. И вернуть информацию из источника, для которого запрос успешно разрешен первым. Для этого мы используем метод any () библиотеки обещаний Bluebird http://bluebirdjs.com/docs/api/promise.any.html

const GetdataPromise = (promises: Array<Promise<any>>) => {
  return new Promise((resolve, reject) =>
    BluebirdPromise.any(promises)
      .then(response => resolve(response))
      .catch(BluebirdPromise.AggregateError, err => reject(err.shift()))
  );
};

export const GetdataData = async (p: string) => {
  const key = `p.${p}`;
    let responsePromises: Array<Promise<any>> = [];
    if (ShouldGetdataData(data)) {
        responsePromises.push(GetdataInfoFromN(p));     
        responsePromises.push(GetdataInfoFromP(p));
    }
}

await GetdataPromise(responsePromises)
        .then((response: any) => {
          logger.info(`final p response received ${p}`, JSON.stringify(response));
          data = response;
          shouldUpdatadataCache = response.success;
        })
        .catch(err => {
          logger.error(err, "error getting p response");
        });
    }
  }
  return !data.success && cachedData.success ? cachedData : data;
};

const GetdataInfoFromP = (p: string): Promise<any> => {
  let url = `${BASE_URL}/api/p=${p}`;
  return new Promise((resolve, reject) => {
    AxiosGet(url, { timeout: 15000 }, "p response", p)
      .then((response: any) => {
        if (response.data.status.result === "success") {
          responseData = ProcessPdataResponse(p, response.data);
          resolve(responseData);
        }
        reject(responseData);
      })
      .catch(err => {
        logger.error(err, `p err ${p}`);
        responseData["RESULT_MESSAGE"] = "Unable to getresponse.";
        reject(responseData);
      });
  });
};

export const GetdataInfoFromN = (p: string): Promise<any> => {
  return new Promise((resolve, reject) => {
    AxiosGet(url, { timeout: 10000, headers: { Authorization: `Basic ${AUTH}` } }, "p response n", p)
      .then((response: any) => {
        if (response.data.dataNumber === p) {
          logger.info(`nGet p info result for p no ${p} ${JSON.stringify(response.data)}`);
          resolve(responseData);
        } else {
          responseData["RESULT_MESSAGE"] = response.data.errorMessage ? response.data.errorMessage.split("-")[0] : "Unable to get P response.";
          reject(responseData);
        }
      })
      .catch(err => {
        responseData["RESULT_MESSAGE"] = "Unable to get p response.";
        logger.error(err, `error in nGet p ${p}`);
        reject(responseData);
      });
  });
}

Проблема, с которой мы сталкиваемся, заключается в том, что, когда обещание отклоняется, возникает исключение и приложение перезапускается. Хотя мы используем catch для его обработки.

Существует несколько исключений, которые генерируются: -

 ERR [2019-10-04 13:33:47,525] [p data] data err p 4364081301 Error: timeout of 15000ms exceeded
    TypeError: this._currentRequest[method] is not a function
        at RedirectableRequest.(anonymous function) (home/data/node_modules/follow-redirects/index.js:139:40)
        at Timeout.handleRequestTimeout [as _onTimeout] (home/data/node_modules/axios/lib/adapters/http.js:216:13)
        at ontimeout (timers.js:498:11)
        at tryOnTimeout (timers.js:323:5)
        at Timer.listOnTimeout (timers.js:290:5)
    TypeError: this._currentRequest[method] is not a function
        at RedirectableRequest.(anonymous function) (home/data/node_modules/follow-redirects/index.js:139:40)
        at Timeout.handleRequestTimeout [as _onTimeout] (home/data/node_modules/axios/lib/adapters/http.js:216:13)
        at ontimeout (timers.js:498:11)
        at tryOnTimeout (timers.js:323:5)
        at Timer.listOnTimeout (timers.js:290:5)
    ERR [2019-10-04 13:33:58,376] [p data] data err paT-mX90rto 2301753220 Error: timeout of 15000ms exceeded
    TypeError: this._currentRequest[method] is not a function
        at RedirectableRequest.(anonymous function) (home/data/node_modules/follow-redirects/index.js:139:40)
        at Timeout.handleRequestTimeout [as _onTimeout] (home/data/node_modules/axios/lib/adapters/http.js:216:13)
        at ontimeout (timers.js:498:11)
        at tryOnTimeout (timers.js:323:5)
        at Timer.listOnTimeout (timers.js:290:5)
    TypeError: this._currentRequest[method] is not a function
        at RedirectableRequest.(anonymous function) (home/data/node_modules/follow-redirects/index.js:139:40)
        at Timeout.handleRequestTimeout [as _onTimeout] (home/data/node_modules/axios/lib/adapters/http.js:216:13)
        at ontimeout (timers.js:498:11)
        at tryOnTimeout (timers.js:323:5)
        at Timer.listOnTimeout (timers.js:290:5)
    ERR [2019-10-04 13:34:13,567] [p data] data err pError: timeout of 15000ms exceeded

Мы используем PM2 в качестве менеджера процессов с двумя кластерами для нашего приложения. Но эти исключения приводят к перезапуску процесса PM2.

┌──────────┬────┬─────────┬─────────┬───────┬────────┬─────────┬────────┬──────┬───────────┬────────┬──────────┐
│ App name │ id │ version │ mode    │ pid   │ status │ restart │ uptime │ cpu  │ mem       │ user   │ watching │
├──────────┼────┼─────────┼─────────┼───────┼────────┼─────────┼────────┼──────┼───────────┼────────┼──────────┤
│ c        │ 2  │ 1.0.0   │ cluster │ 15057 │ online │ 31041   │ 18s    │ 5.2% │ 61.5 MB   │ ubuntu │ disabled │
│ c        │ 3  │ 1.0.0   │ cluster │ 15131 │ online │ 31003   │ 14s    │ 0%   │ 50.4 MB   │ ubuntu │ disabled │
└──────────┴────┴─────────┴─────────┴───────┴────────┴─────────┴────────┴──────┴───────────┴────────┴──────────┘

Мы пытались вернуть обещание (responseData), пытались вернуть обещание объекта err (err) из GetdataInfoFromP () и GetdataInfoFromN (), но безуспешно.

Любая помощь будет принята с благодарностью.

...