@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
JavaScript
;
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,
};