UNPKG

@saboosanket/code-generator

Version:

This npm package is a versatile setup tool tailored for Node.js projects, enabling users to generate customized project structures and functionalities. It supports integration with Google Cloud Platform (GCP), RabbitMQ, Redis, a Prisma query generator, an

161 lines (153 loc) 6.15 kB
import { createModuleAndFile, writeFileWithoutPrompt } from '../utils/write_files.js' import { customErrors } from '../base_scaffolding/custom_error.js' const httpFileContent = ` import axios from 'axios' import get from 'lodash/get.js' import { customSleep } from './utils.services.js' import { HTTPError, UnexpectedError } from './custom_error.js' import { INTERNAL_SERVER_ERROR } from './constants.js' /** * Makes an HTTP request with exponential backoff retry capability. * * @param {Object} http_details - The details of the HTTP request. * @param {string} http_details.method - The HTTP method (e.g., 'get', 'post', 'put', 'delete'). * @param {string} http_details.url - The URL for the HTTP request. * @param {Object} [http_details.headers] - The headers to include in the request. * @param {Object} [http_details.params] - The parameters to include in the request body for POST/PUT requests. - Optional for get types * @param {string} [http_details.response_type] - Optional. The response type (e.g., 'json', 'arraybuffer'). If mentioned defaults to json according to axios * @param {number[]} [http_details.no_retry_status_codes=[400, 401, 403, 404, 405, 413, 414]] - Optional. Status codes that should not trigger a retry. * @param {number} [http_details.base_value_of_exponential_wait_time=2] - Optional. Base value for exponential backoff wait time. * @param {number} [http_details.max_power_of_exponential_wait_time=2] - Optional. Maximum power for exponential backoff wait time. * @param {number} [max_retries=3] - Optional. The maximum number of retry attempts in case of failure. * @param {number} [current_retry=0] - Optional. The current retry attempt number. Don't pass it while calling function * @returns {Promise<Object>} The response from the HTTP request. * @throws {HTTPError} Throws a custom HTTPError on failure with a message and optional data. */ async function httpCall(http_details, max_retries = 3, current_retry = 0) { const method = get(http_details, 'method') const url = get(http_details, 'url') const headers = get(http_details, 'header', '') const params = get(http_details, 'params', {}) const responseType = get(http_details, 'response_type', '') const no_retry_status_codes = get( http_details, 'no_retry_status_codes', [400, 401, 403, 404, 405, 413, 414] ) const base_value_of_exponential_wait_time = get( http_details, 'base_value_of_exponential_wait_time', 2 ) const max_power_of_exponential_wait_time = get( http_details, 'max_power_of_exponential_wait_time', 2 ) const config = { method, url, ...(headers && { headers }), ...(responseType && { responseType }), ...(method === 'get' && { params }), ...(['post', 'put'].includes(method) && { data: params }) } try { const response = await axios(config) const status_code = response.status console.log('Status Code:', status_code) if (status_code >= 200 && status_code < 300) { return response } if ( current_retry < max_retries && !no_retry_status_codes.includes(status_code) ) { console.log(\`current_retrying \${current_retry} attempts left...\`) const wait_time_ms = base_value_of_exponential_wait_time ** Math.min( current_retry, max_power_of_exponential_wait_time ) * 1000 await customSleep(wait_time_ms) return await httpCall(http_details, max_retries, current_retry + 1) } else { console.log( 'MAx retries reached or status_code in no_retry_status_codes' ) throw HTTPError( 'Max retries reached or status_code in no_retry_status_codes.', status_code, { message: 'Max retries reached or status_code in no_retry_status_codes.', data: response.data } ) } } catch (error) { console.error('Error making HTTP request:') if (error.name === 'HTTPError') { throw error } if (error.response && error.response.data) { throw HTTPError( 'Error making HTTP request', error.response.status, { message: 'Error making HTTP request', data: error.response.data } ) } throw UnexpectedError(INTERNAL_SERVER_ERROR, 500, { message: INTERNAL_SERVER_ERROR, data: sanitizeError(error) }) } } function sanitizeError(error) { try { // If no error, return as is if (!error) { return error } const sanitizedError = { ...error } // Remove headers from config if (sanitizedError.config && sanitizedError.config.headers) { delete sanitizedError.config.headers } // Remove headers from request (ClientRequest) if (sanitizedError.request) { deleteHeadersFromErrorLogs(sanitizedError.request) } return sanitizedError } catch (error) { return 'Unknown sanitization error' } } function deleteHeadersFromErrorLogs(sanitizedErrorRequest) { if (sanitizedErrorRequest._headers) { delete sanitizedErrorRequest._headers } if ( sanitizedErrorRequest._currentRequest && sanitizedErrorRequest._currentRequest._header ) { delete sanitizedErrorRequest._currentRequest._header } } export { httpCall } ` async function createHttpFile() { const folderName = 'services/http_module' const fileName = 'http_call.services.js' await createModuleAndFile(folderName, fileName, httpFileContent) await writeFileWithoutPrompt('services', 'custom_error.js', customErrors) } export { createHttpFile }