Я смотрю на ошибку, возникающую в нашем производственном приложении. Это приложение на основе 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 (), но безуспешно.
Любая помощь будет принята с благодарностью.