diff --git a/core/in_queue.js b/core/in_queue.js index cee141a..90a93f5 100644 --- a/core/in_queue.js +++ b/core/in_queue.js @@ -152,6 +152,8 @@ class InQueue extends EventEmitter { sOptions: buildOptionsXML({ options }), blMsg }); + //Запомним идентификатор записи очереди в запросе + prms.req.nQId = q.nId; //Скажем что пришло новое входящее сообщение await this.logger.info( `Новое входящее сообщение от ${prms.req.connection.address().address} для функции ${prms.function.sCode} (${buildURL({ @@ -329,13 +331,19 @@ class InQueue extends EventEmitter { } } } - //Если мы еще не отдали ответ от сервера - if (!prms.res.writableFinished) { - //Всё успешно - отдаём результат клиенту - if (bStopPropagation === false) { - if (optionsResp.headers) prms.res.set(optionsResp.headers); - prms.res.status(optionsResp.statusCode || 200).send(blResp); - } + //Всё успешно - отдаём результат клиенту, если ещё не отдали + if (bStopPropagation === false && !prms.res.writableFinished) { + if (optionsResp.headers) prms.res.set(optionsResp.headers); + prms.res.status(optionsResp.statusCode || 200).send(blResp); + } + //Если отправка ответа была прервана по таймауту + if (prms.req.bIsTimedOut === true) { + //Вернем ошибку обработчика с информацией об этом + throw new ServerError( + SERR_WEB_SERVER, + "Истекло время ожидания обработки входящего запроса. Канал закрыт. Клиенту был отправлен ответ с ошибкой истечения таймаута (504)." + ); + } else { //Фиксируем успех обработки - в протоколе работы сервиса await this.logger.info(`Входящее сообщение ${q.nId} успешно отработано`, { nQueueId: q.nId }); //Фиксируем успех обработки - в статусе сообщения @@ -344,12 +352,6 @@ class InQueue extends EventEmitter { nIncExecCnt: NINC_EXEC_CNT_YES, nExecState: objQueueSchema.NQUEUE_EXEC_STATE_OK }); - } else { - //Или расскажем об ошибке - throw new ServerError( - SERR_WEB_SERVER, - "Истекло время ожидания обработки входящего запроса. Канал закрыт. Клиенту был отправлен ответ." - ); } } catch (e) { //Тема и текст уведомления об ошибке @@ -555,21 +557,24 @@ class InQueue extends EventEmitter { if (req.headers["content-type"] === "false") req.headers["content-type"] = "application/octet-stream"; next(); }); - //Если требуется установить таймаут на обработку сообщений - if (this.inComing.nTimeout !== 0) { - //Конфигурируем сервер - устанавливаем таймаут обработки сообщений - this.webApp.use((req, res, next) => { + //Конфигурируем сервер - устанавливаем таймаут обработки сообщений + this.webApp.use((req, res, next) => { + //Поднимем флаг истечения таймаута обработки + req.bIsTimedOut = false; + //Если требуется установить таймаут на обработку сообщений + if (this.inComing.nTimeout !== 0) //Устанавливаем таймаут на ответ от сервера res.setTimeout(this.inComing.nTimeout, () => { + //Поднимем флаг исчетечение таймаута обработки + req.bIsTimedOut = true; //Формируем ошибку let err = new Error("Истекло время ожидания формирования ответа для завершения текущего запроса."); err.status = 504; //Отправляем ошибку next(err); }); - next(); - }); - } + next(); + }); //Конфигурируем сервер - обработка тела сообщения this.webApp.use(bodyParser.raw({ limit: `${this.inComing.nMsgMaxSize}mb`, type: "*/*" })); //Конфигурируем сервер - обходим все сервисы, работающие на приём сообщений @@ -624,7 +629,8 @@ class InQueue extends EventEmitter { //Протоколируем в журнал работы сервера await this.logger.error(makeErrorText(new ServerError(SERR_WEB_SERVER, err.message)), { nServiceId: srvs.nId, - nServiceFnId: fn.nId + nServiceFnId: fn.nId, + nQueueId: req.nQId || null }); //Отправим ошибку клиенту res.status(err.status || 500).send(makeErrorText(new ServerError(SERR_WEB_SERVER, err.message)));