UNPKG

@ministryofjustice/hmpps-digital-prison-reporting-frontend

Version:

The Digital Prison Reporting Frontend contains templates and code to help display data effectively in UI applications.

139 lines (138 loc) 6.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.shouldTimeoutRequest = exports.getExpiredStatus = exports.getStatus = void 0; const dayjs_1 = __importDefault(require("dayjs")); const UserReports_1 = require("../types/UserReports"); const logger_1 = __importDefault(require("./logger")); const localsHelper_1 = __importDefault(require("./localsHelper")); const BAD_REQUEST_STATUSES = [UserReports_1.RequestStatus.ABORTED, UserReports_1.RequestStatus.FAILED, UserReports_1.RequestStatus.EXPIRED]; const IN_PROGRESS_REQUEST_STATUSES = [ UserReports_1.RequestStatus.SUBMITTED, UserReports_1.RequestStatus.STARTED, UserReports_1.RequestStatus.PICKED, ]; function findWorstStatusResponse(statusRequests) { return Promise.all(statusRequests).then((statusResponses) => { const badStatus = statusResponses.find((response) => typeof response.status === 'number' || BAD_REQUEST_STATUSES.includes(response.status)); if (badStatus) { return badStatus; } const inProgressStatus = statusResponses.find((response) => IN_PROGRESS_REQUEST_STATUSES.includes(response.status)); if (inProgressStatus) { return inProgressStatus; } return statusResponses[0]; }); } const getStatusByReportType = async (services, req, res, token, userId) => { var _a; const { definitionsPath } = localsHelper_1.default.getValues(res); const { type, reportId, executionId, id, tableId } = req.body; const requestedReport = await services.requestedReportService.getReportByExecutionId(executionId, userId); const reports = (_a = requestedReport.childExecutionData) !== null && _a !== void 0 ? _a : []; if (type === UserReports_1.ReportType.REPORT) { reports.push({ executionId, tableId, variantId: id }); } const statusRequests = reports.map((executionData) => services.reportingService.getAsyncReportStatus(token, reportId, executionData.variantId, executionData.executionId, definitionsPath, executionData.tableId)); if (type === UserReports_1.ReportType.DASHBOARD) { statusRequests.push(services.dashboardService.getAsyncStatus(token, reportId, id, executionId, definitionsPath, tableId)); } const statusResponse = await findWorstStatusResponse(statusRequests); return { status: statusResponse.status, statusResponse, }; }; const getStatus = async ({ req, res, services }) => { const { token, userId } = localsHelper_1.default.getValues(res); const { status: currentStatus, requestedAt } = req.body; const timeoutExemptStatuses = [UserReports_1.RequestStatus.READY, UserReports_1.RequestStatus.EXPIRED, UserReports_1.RequestStatus.FAILED]; let status; let errorMessage; let statusResponse; try { ; ({ status, statusResponse } = await getStatusByReportType(services, req, res, token, userId)); if ((0, exports.shouldTimeoutRequest)({ requestedAt, compareTime: new Date(), durationMins: 15 }) && !timeoutExemptStatuses.includes(status)) { throw new Error('Request taking too long. Request Halted'); } if (status === UserReports_1.RequestStatus.FAILED) { logger_1.default.error(`Error: ${JSON.stringify(statusResponse.error)}`); const { userMessage, developerMessage } = statusResponse.error; if (userMessage || developerMessage) { errorMessage = statusResponse.error; } else { errorMessage = { developerMessage: statusResponse.error, }; } } } catch (error) { logger_1.default.error(`Error: ${JSON.stringify(error)}`); const { data } = error; errorMessage = data || { userMessage: error.message }; status = currentStatus === UserReports_1.RequestStatus.FINISHED ? UserReports_1.RequestStatus.EXPIRED : UserReports_1.RequestStatus.FAILED; } if (typeof status === 'number') { status = UserReports_1.RequestStatus.FAILED; } return { status, ...(errorMessage && { errorMessage }), }; }; exports.getStatus = getStatus; /** * Gets the expired status of a viewed report * - if reports status was READY/FINISHED * - And the new Status is an error status * - it means the report has expired * * @param {AsyncReportUtilsParams} { req, res, services } * @return {*} */ const getExpiredStatus = async ({ req, res, services }) => { const { token, userId } = localsHelper_1.default.getValues(res); const { executionId, status: currentStatus } = req.body; let errorMessage; let status; try { ; ({ status } = await getStatusByReportType(services, req, res, token, userId)); } catch (error) { const { data } = error; errorMessage = (data !== null && data !== void 0 ? data : {}).userMessage; status = currentStatus === UserReports_1.RequestStatus.READY || currentStatus === UserReports_1.RequestStatus.FINISHED ? UserReports_1.RequestStatus.EXPIRED : UserReports_1.RequestStatus.FAILED; } const result = { status, ...(errorMessage && { errorMessage }), }; return { isExpired: result.status === UserReports_1.RequestStatus.EXPIRED, executionId, }; }; exports.getExpiredStatus = getExpiredStatus; const shouldTimeoutRequest = ({ requestedAt, compareTime, durationMins, }) => { const compareDate = (0, dayjs_1.default)(compareTime); const requestDate = (0, dayjs_1.default)(requestedAt); const result = compareDate.diff(requestDate, 'minutes'); return result >= durationMins; }; exports.shouldTimeoutRequest = shouldTimeoutRequest; exports.default = { getStatus: exports.getStatus, getExpiredStatus: exports.getExpiredStatus, shouldTimeoutRequest: exports.shouldTimeoutRequest, };