Skip to content

Commit

Permalink
Merge pull request #2280 from HHS/mb/revert-transactions-for-workers
Browse files Browse the repository at this point in the history
Revert "Merge pull request #2233 from HHS/TTAHUB-3097/worker-transact…
  • Loading branch information
thewatermethod authored Jul 19, 2024
2 parents a3ff0df + 6b53dbe commit 6f79381
Show file tree
Hide file tree
Showing 16 changed files with 158 additions and 617 deletions.
2 changes: 1 addition & 1 deletion email_templates/changes_requested_by_manager/html.pug
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ style
include ../email.css
p Hello,
p
p #{managerName} requested changes to report #{displayId}.
p #{managerName} requested changed to report #{displayId}.
if comments
p #{managerName} provided the following comments:
blockquote !{comments}
Expand Down
179 changes: 44 additions & 135 deletions src/lib/apiErrorHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,34 @@ import { sequelize } from '../models';
* @returns {Promise<number|null>} - The ID of the stored request error, or null if storing failed.
*/
async function logRequestError(req, operation, error, logContext) {
// Check if error logging should be suppressed
if (
operation !== 'SequelizeError'
&& process.env.SUPPRESS_ERROR_LOGGING
&& process.env.SUPPRESS_ERROR_LOGGING.toLowerCase() === 'true'
) {
return 0;
}
if (!error) {
return 0;
}

try {
// Prepare the response body for storage
const responseBody = typeof error === 'object'
? { ...error, errorStack: error?.stack }
: error;
&& error !== null ? { ...error, errorStack: error?.stack } : error;

// Prepare the request body for storage
const requestBody = {
...(req.body && typeof req.body === 'object' && Object.keys(req.body).length > 0 && { body: req.body }),
...(req.params && typeof req.params === 'object' && Object.keys(req.params).length > 0 && { params: req.params }),
...(req.query && typeof req.query === 'object' && Object.keys(req.query).length > 0 && { query: req.query }),
...(req.body
&& typeof req.body === 'object'
&& Object.keys(req.body).length > 0
&& { body: req.body }),
...(req.params
&& typeof req.params === 'object'
&& Object.keys(req.params).length > 0
&& { params: req.params }),
...(req.query
&& typeof req.query === 'object'
&& Object.keys(req.query).length > 0
&& { query: req.query }),
};

// Create a request error in the database and get its ID
Expand Down Expand Up @@ -61,13 +69,15 @@ async function logRequestError(req, operation, error, logContext) {
* @param {Object} logContext - The context for logging.
*/
export const handleError = async (req, res, error, logContext) => {
// Check if the environment is development
if (process.env.NODE_ENV === 'development') {
logger.error(error);
}

let operation;
let label;

// Check if the error is an instance of Sequelize.Error
if (error instanceof Sequelize.Error) {
operation = 'SequelizeError';
label = 'Sequelize error';
Expand All @@ -76,17 +86,27 @@ export const handleError = async (req, res, error, logContext) => {
label = 'UNEXPECTED ERROR';
}

if (error instanceof Sequelize.ConnectionError
|| error instanceof Sequelize.ConnectionAcquireTimeoutError) {
// eslint-disable-next-line max-len
if (error instanceof Sequelize.ConnectionError || error instanceof Sequelize.ConnectionAcquireTimeoutError) {
const pool = sequelize?.connectionManager?.pool;
const usedConnections = pool ? pool.used.length : null;
const waitingConnections = pool ? pool.pending.length : null;
const usedConnections = pool ? pool?.used?.length : null;
const waitingConnections = pool ? pool?.pending?.length : null;
logger.error(`${logContext.namespace} Connection Pool: Used Connections - ${usedConnections}, Waiting Connections - ${waitingConnections}`);
}

// Log the request error and get the error ID
const requestErrorId = await logRequestError(req, operation, error, logContext);

const errorMessage = error?.stack || error;
let errorMessage;

// Check if the error has a stack property
if (error?.stack) {
errorMessage = error.stack;
} else {
errorMessage = error;
}

// Log the error message with the error ID if available
if (requestErrorId) {
logger.error(`${logContext.namespace} - id: ${requestErrorId} ${label} - ${errorMessage}`);
} else {
Expand All @@ -97,11 +117,12 @@ export const handleError = async (req, res, error, logContext) => {
};

/**
* Handles any unexpected errors in an error handler catch block.
* @param {Object} req - The request object.
* @param {Object} res - The response object.
* @param {Error} error - The error object.
* @param {Object} logContext - The context for logging.
* Handles any unexpected errors in an error handler catch block
*
* @param {*} req - request
* @param {*} res - response
* @param {*} error - error
* @param {*} logContext - useful data for logging
*/
export function handleUnexpectedErrorInCatchBlock(req, res, error, logContext) {
logger.error(`${logContext.namespace} - Unexpected error in catch block - ${error}`);
Expand All @@ -110,10 +131,11 @@ export function handleUnexpectedErrorInCatchBlock(req, res, error, logContext) {

/**
* Handles API errors. Saves data in the RequestErrors table and sends 500 error.
* @param {Object} req - The request object.
* @param {Object} res - The response object.
* @param {Error} error - The error object.
* @param {Object} logContext - The context for logging.
*
* @param {*} req - request
* @param {*} res - response
* @param {*} error - error
* @param {*} logContext - useful data for logging
*/
export default async function handleErrors(req, res, error, logContext) {
try {
Expand All @@ -122,116 +144,3 @@ export default async function handleErrors(req, res, error, logContext) {
handleUnexpectedErrorInCatchBlock(req, res, e, logContext);
}
}

/**
* Logs a worker error and stores it in the database.
* @param {Object} job - The job object.
* @param {string} operation - The operation name.
* @param {Error} error - The error object.
* @param {Object} logContext - The logging context.
* @returns {Promise<number|null>} - The ID of the stored request error, or null if storing failed.
*/
const logWorkerError = async (job, operation, error, logContext) => {
if (
operation !== 'SequelizeError'
&& process.env.SUPPRESS_ERROR_LOGGING
&& process.env.SUPPRESS_ERROR_LOGGING.toLowerCase() === 'true'
) {
return 0;
}
if (!error) {
return 0;
}

try {
const responseBody = typeof error === 'object'
? { ...error, errorStack: error?.stack }
: error;

const requestBody = {
...(job.data && typeof job.data === 'object' && Object.keys(job.data).length > 0 && { data: job.data }),
};

const requestErrorId = await createRequestError({
operation,
uri: job.queue.name,
method: 'PROCESS_JOB',
requestBody,
responseBody,
responseCode: INTERNAL_SERVER_ERROR,
});

return requestErrorId;
} catch (e) {
logger.error(`${logContext.namespace} - Sequelize error - unable to store RequestError - ${e}`);
}

return null;
};

/**
* Handles errors in a worker job.
* @param {Object} job - The job object.
* @param {Error} error - The error object.
* @param {Object} logContext - The context for logging.
*/
export const handleWorkerError = async (job, error, logContext) => {
if (process.env.NODE_ENV === 'development') {
logger.error(error);
}

let operation;
let label;

if (error instanceof Sequelize.Error) {
operation = 'SequelizeError';
label = 'Sequelize error';
} else {
operation = 'UNEXPECTED_ERROR';
label = 'UNEXPECTED ERROR';
}

if (error instanceof Sequelize.ConnectionError
|| error instanceof Sequelize.ConnectionAcquireTimeoutError) {
const pool = sequelize?.connectionManager?.pool;
const usedConnections = pool ? pool.used.length : null;
const waitingConnections = pool ? pool.pending.length : null;
logger.error(`${logContext.namespace} Connection Pool: Used Connections - ${usedConnections}, Waiting Connections - ${waitingConnections}`);
}

const requestErrorId = await logWorkerError(job, operation, error, logContext);

const errorMessage = error?.stack || error;

if (requestErrorId) {
logger.error(`${logContext.namespace} - id: ${requestErrorId} ${label} - ${errorMessage}`);
} else {
logger.error(`${logContext.namespace} - ${label} - ${errorMessage}`);
}

// Handle job failure as needed
};

/**
* Handles any unexpected errors in a worker error handler catch block.
* @param {Object} job - The job object.
* @param {Error} error - The error object.
* @param {Object} logContext - The context for logging.
*/
export const handleUnexpectedWorkerError = (job, error, logContext) => {
logger.error(`${logContext.namespace} - Unexpected error in catch block - ${error}`);
};

/**
* Handles worker job errors. Logs the error and stores it in the database.
* @param {Object} job - The job object.
* @param {Error} error - The error object.
* @param {Object} logContext - The context for logging.
*/
export const handleWorkerErrors = async (job, error, logContext) => {
try {
await handleWorkerError(job, error, logContext);
} catch (e) {
handleUnexpectedWorkerError(job, e, logContext);
}
};
Loading

0 comments on commit 6f79381

Please sign in to comment.