UNPKG

identi-recognition

Version:

identiRecognition

704 lines (637 loc) 29.1 kB
// --- DEPENDENCIES --- const fs = require('fs') const FormData = require('form-data') // --- IMPORTS --- const config = require('../config') const { validateIPaddress, isValidDate } = require('../utils/utils') const { requestGetCall, requestCallRest, isAxiosError } = require('../utils/requestCall') const { handleHttpError, throwCustomError, hfSecHerror } = require('../utils/errorHandler') const CODES = require('../utils/codes') /** * @typedef {Object} XCore * @property {JSON} preparedReport Object to be defined before generating a reporte * @property {Function} getStatus Validate if the device is available to be used */ class XCore { /** * Creates an instance of `DeviceHandler`. * The constructor initializes the device handler with a specified IP address and configures the base URL * based on whether it is a professional or standard version of the device. * * @param {string} ip - The IP address of the device to connect to. * @param {boolean} [_versionPro=true] - Specifies whether to use the professional version of the API (`/v1/MEGBOX`) * or the standard version (`/v1/BOX`). Defaults to `true` for professional version. * * @throws {Error} Throws an error if the provided IP address is invalid. * * @example * // Create an instance using a valid IP address for the professional version: * const device = new DeviceHandler('192.168.1.100'); * * // Create an instance for the standard version of the device: * const device = new DeviceHandler('192.168.1.100', false); */ constructor(ip, _versionPro = true) { try { if (!validateIPaddress(ip)) throw new Error('Invalid ip received', { ...CODES.HFS003 }) this.ip = ip this.baseUrl = _versionPro ? `http://${ip}/v1/MEGBOX` : `http://${ip}/v1/BOX` this.preparedReport } catch (error) { throw new hfSecHerror(error) } } /** * Asynchronously retrieves and validates the configuration status of the device. * The `getStatus` function sends a request to the device's configuration endpoint * to verify if the device is properly configured and operational. * * @returns {boolean} Returns `true` if the device configuration is valid and operational. * * @throws {hfSecHerror} Throws a custom `hfSecHerror` if the `modelSw` property is missing * in the device configuration data or if an unexpected error occurs. * */ async getStatus() { try { const deviceConfiguration = await requestGetCall(this.baseUrl, config.endpoints.xcore.configuration) const dataDevice = deviceConfiguration?.data if (dataDevice?.code != 0) throw new Error('Error on device configuration', { ...CODES.HFS004 }) if (!dataDevice?.data.hasOwnProperty('modelSw')) { throw new hfSecHerror({ message: 'Error on device configuration', ...CODES.HFS004 }) } return true } catch (error) { if (error instanceof hfSecHerror) { throw error } throw new hfSecHerror({ message: `XCORE Device start With Errors`, ...CODES.HFS004, baseError: error?.message }) } } /** * Compares two base64-encoded face images to determine if they match. * The `facesCompare` function sends the images as `form-data` to the device's API endpoint for face comparison. * It supports an optional liveness check that can be enabled or disabled during the comparison. * * @param {string} image1 - A base64-encoded string representing the first face image. * @param {string} image2 - A base64-encoded string representing the second face image. * @param {boolean} [liveness=true] - Indicates whether to perform a liveness check during face comparison. * If `true`, liveness verification is enabled; otherwise, it is disabled. Default is `true`. * * @returns {Object} Returns an object containing the result of the comparison, * along with the status code (`CODES.HFS001`) and the `message` property with the API response. * * @throws {hfSecHerror} Throws a custom `hfSecHerror` if required parameters (`image1` or `image2`) are missing, * or if there is an issue with the API request. * * @example * // Example usage: * try { * const comparisonResult = await instance.facesCompare(base64Image1, base64Image2); * console.log("Comparison result:", comparisonResult.message); * } catch (err) { * console.error("Face comparison failed:", err); * } */ async facesCompare(image1, image2, liveness = true) { try { if (!image1 || !image2) throw new hfSecHerror({ message: `Missing required parameters : [${!image1 ? 'image1,' : ''}${!image2 ? 'image2' : ''}]`, ...CODES.HFS002 }) const image1Buffer = Buffer.from(image1, 'base64') const image2Buffer = Buffer.from(image2, 'base64') const form = new FormData() form.append('image1', image1Buffer, { filename: `image1.jpg`, 'Content-Type': 'image/jpeg' }) form.append('image2', image2Buffer, { filename: `image2.jpg`, 'Content-Type': 'image/jpeg' }) form.append('livenessEnabled', liveness ? 'true' : 'false') const fixedHeader = { ...form.getHeaders(), 'Content-Length': form.getLengthSync() } const result = await requestCallRest(this.baseUrl, config.endpoints.xcore.compare, 'POST', form, fixedHeader) return { ...CODES.HFS001, message: result.data } } catch (error) { if (error instanceof hfSecHerror) { throw error } throw new hfSecHerror({ message: 'Error on device configuration', ...CODES.HFS004, baseError: error?.message }) } } async faceCompareToLocal(image, group, liveness = true) { try { if (!image) throw new hfSecHerror({ message: `Missing required parameter image `, ...CODES.HFS002 }) if (!group) throw new hfSecHerror({ message: `Missing required parameter group `, ...CODES.HFS002 }) if (!Array.isArray(group)) throw new hfSecHerror({ message: `Invalid required parameter group. It must be an Array. Ex: ['Identica'] `, ...CODES.HFS002 }) const image1Buffer = Buffer.from(image, 'base64') const form = new FormData() form.append('image', image1Buffer, { filename: `image.jpg`, 'Content-Type': 'image/jpeg' }) form.append('group', `["${group}"]`) form.append('livenessEnabled', liveness ? 'true' : 'false') const fixedHeader = { ...form.getHeaders(), 'Content-Length': form.getLengthSync() } const result = await requestCallRest(this.baseUrl, config.endpoints.xcore.oneToN, 'POST', form, fixedHeader) return { ...CODES.HFS001, message: result.data } } catch (error) { if (error instanceof hfSecHerror) { throw error } throw new hfSecHerror({ message: 'Error on device configuration', ...CODES.HFS004, baseError: error?.message }) } } /** * The function `prepareReport` asynchronously prepares a report telling user how much infomration * does the time will have. Reports works with pagination. * @param { string } timeStart - (dd/MM/YYYY HH:mm) Represents the start time for the report. * @param { string } timeEnd- (dd/MM/YYYY HH:mm) Represents the end time for the report data that you want to retrieve * @param { number } [pageSize=10] - Specifies the number of items to be displayed per page in the report * @param { boolean } [knownPeople=true] - It is a numeric value that determines the nature of the * report or data retrieval operation. In the function, the `queryType` parameter is set to a default * value of ` * @param { boolean } [deduplicate=false] - Specify if duplicated detected users will be * removed from the report results.When `deduplicate` is set to true, duplicate entries will be removed * and when it is set to false, duplicate entries will not, and will generate ALL LOGS * @param { string } [_specifyUser=null] - Used to specify a unique user for the report. * @returns The `prepareReport` function returns the `preparedReport` object containing information * such as `timeStart`, `timeEnd`, `pageSize`, `queryType`, `deduplicate`, `totalAlerts`, and * `totalPages`. This object is populated with data retrieved from an API call to `requestGetCall` * using specified parameters. If there are any errors during the process, a custom error object */ async prepareReport(timeStart, timeEnd, pageSize = 10, knownPeople = true, deduplicate = false, _specifyUser = null) { try { if (!isValidDate(timeStart) || !isValidDate(timeEnd)) throw new hfSecHerror({ message: 'Invalid time start or end', ...CODES.HFS002 }) if (isNaN(pageSize)) throw new hfSecHerror({ message: 'pageSize parameter received is not a number', ...CODES.HFS002 }) if (pageSize > 20) throw new hfSecHerror({ message: 'pageSize max is 20', ...CODES.HFS002 }) if (!(typeof knownPeople == 'boolean')) throw new hfSecHerror({ message: 'Invalid knownPeople received', ...CODES.HFS002 }) if (!(typeof deduplicate == 'boolean')) throw new hfSecHerror({ message: 'Invalid deduplicate received', ...CODES.HFS002 }) if (!(_specifyUser && typeof _specifyUser == 'string')) { _specifyUser = null } this.preparedReport = { timeStart, timeEnd, pageSize: Math.floor(pageSize), queryType: knownPeople ? 1 : 2, deduplicate: deduplicate ? 1 : 0, totalAlerts: null, totalPages: null } const parameters = { timeStart: new Date(timeStart).getTime() / 1000, timeEnd: new Date(timeEnd).getTime() / 1000, pageToken: 0, pageSize: this.preparedReport.pageSize, QueryType: this.preparedReport.queryType, Dedup: this.preparedReport.deduplicate, faceToken: undefined } const response = await requestGetCall(this.baseUrl, config.endpoints.xcore.alertLogs, parameters) if (!response || response?.data?.code != 0) { const errorMessage = `[${arguments.callee.name}] xcore not responding` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS004, baseErrorCode: response?.data?.code }) } this.preparedReport.totalAlerts = response?.data?.data?.totalAlarts this.preparedReport.totalPages = Math.ceil(response?.data?.data?.totalAlarts / this.preparedReport.pageSize) return this.preparedReport } catch (error) { if (error instanceof hfSecHerror) { throw error } const errorMessage = `[${arguments.callee.name}] xcore not responding` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS006, baseError: error?.message }) } } /** * The function `generateReport` asynchronously generates a report file with data specified with the * `prepareReport` function * @param {string} fileName Specific name or path of the file that will be created and not overwritted. * @returns The `generateReport` function returns an object with the `fileName` and `fileSize` * properties if the report generation is successful. If any errors occur during the process, it throws * a custom error object of type `hfSecHerror`. */ async generateReport(fileName) { try { if (!this.preparedReport) throw new hfSecHerror({ message: 'Call "prepareReport" function before generating reporte', ...CODES.HFS003 }) if (!fileName || typeof fileName != 'string') throw new hfSecHerror({ message: 'Invalid fileName parameter', ...CODES.HFS002 }) if (fs.existsSync(fileName)) { const errorMessage = `File "${fileName}" already exists.` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS002 }) } const titleFile = `*** REPORT GENERATED FOR : ${this.preparedReport.timeStart} to ${this.preparedReport.timeEnd} ***` fs.writeFileSync(fileName, titleFile) for (let i = 0; i < 2; i++) { // this.preparedReport.totalPages const reportData = await this._fetchReportData(i) reportData.forEach((item) => { delete item.top4 delete item.top5 delete item.faceAttr }) fs.appendFileSync(fileName, `--- Report Iteration ${i + 1} ---\n`) fs.appendFileSync(fileName, JSON.stringify(reportData, null, '\t')) fs.appendFileSync(fileName, '\n\n') } const fileSize = fs.statSync(fileName).size return { fileName, fileSize } } catch (error) { if (error instanceof hfSecHerror) { throw error } const errorMessage = `[${arguments.callee.name}] xcore not responding` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS006, baseError: error?.message }) } } async _fetchReportData(pageToConsult) { try { const parameters = { timeStart: new Date(this.preparedReport.timeStart).getTime() / 1000, timeEnd: new Date(this.preparedReport.timeEnd).getTime() / 1000, pageToken: pageToConsult, pageSize: this.preparedReport.pageSize, QueryType: this.preparedReport.queryType, Dedup: this.preparedReport.deduplicate, faceToken: undefined } const response = await requestGetCall(this.baseUrl, config.endpoints.xcore.alertLogs, parameters) console.log(response) if (!response || response?.data?.code != 0) { const errorMessage = `[${arguments.callee.name}] xcore not responding` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS004, baseErrorCode: response?.data?.code }) } return response.data.data.alertsEvent } catch (error) { if (error instanceof hfSecHerror) { throw error } const errorMessage = `[${arguments.callee.name}] xcore not responding` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS006, baseError: error?.message }) } } // ---------------------------------------------------------------- // ---------------------------------------------------------------- // ---------------------------------------------------------------- // __ __ _ _ // | \/ |__ _ _ _ __ _ __ _ ___ | | | |___ ___ _ _ ___ // | |\/| / _` | ' \/ _` / _` / -_) | |_| (_-</ -_) '_(_-< // |_| |_\__,_|_||_\__,_\__, \___| \___//__/\___|_| /__/ // |___/ // ---------------------------------------------------------------- // ---------------------------------------------------------------- // ---------------------------------------------------------------- /** * Adds a face, identified by a `faceToken`, to one or more predefined face groups in the system. * The `groupFace` function sends a request to associate a specified face with a list of face groups. * It ensures that the `faceToken` is valid and correctly formatted before sending the request. * * @param {string} faceToken - A unique identifier for the face to be grouped. Must be a 24-character string. * @param {string[]} [faceGroupList=['Identica']] - An array of strings representing the group(s) to which * the face should be added. Defaults to `['Identica']` if not provided. * * @returns {boolean} Returns `true` if the face is successfully added to the specified group(s). * * @throws {hfSecHerror} Throws a custom `hfSecHerror` if the `faceToken` is invalid, if the request fails, * or if the device's API returns an unexpected response. * * @example * // Example usage: * try { * const result = await device.groupFace("5f8d0d55b54764421b7156bb", ["Employees", "VIPs"]); * console.log("Face grouped successfully:", result); * } catch (err) { * console.error("Failed to group face:", err); * } */ async groupFace(faceToken, faceGroupList = ['Identica']) { try { if (!(typeof faceToken == 'string')) throw new hfSecHerror({ message: 'Invalid faceToken parameter', ...CODES.HFS002 }) if (faceToken.length != 24) throw new hfSecHerror({ message: 'Invalid faceToken parameter', ...CODES.HFS002 }) const requestData = { faceGroupList: faceGroupList } const response = await requestCallRest( this.baseUrl, `${config.endpoints.xcore.groupFace}/${faceToken}`, 'POST', requestData ) if (!response || response?.data?.code != 0) { const errorMessage = `[${arguments.callee.name}] xcore device not responding` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS004, baseErrorCode: response?.data?.code }) } return true } catch (error) { if (error instanceof hfSecHerror) { throw error } if (isAxiosError(error)) { const errorMessage = `isAxiosError: ${error?.response?.data ? error.response.data.code + '-' + error.response.data.message : '[UNKOWN ERROR]' + error}` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS005, baseError: error?.message }) } const errorMessage = `[${arguments.callee.name}] Uncatched Error` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS006, baseError: error?.message }) } } /** * @develop * @param {*} id * @param {*} faceImage * @param {*} userDescriptionObject * @returns */ async createUser(id, faceImage, userDescriptionObject) { try { if (!id) throw new hfSecHerror({ message: 'Invalid id parameter received', ...CODES.HFS002 }) if (!faceImage) throw new hfSecHerror({ message: 'Invalid faceImage parameter received', ...CODES.HFS002 }) const userDescription = { id: id, ...userDescriptionObject } const xcoreUploaded = await this._faceUpload(faceImage, userDescription) return { id: id, idXcore: xcoreUploaded.data.faceToken, imageId: xcoreUploaded.data.imageId } } catch (error) { if (error instanceof hfSecHerror) { throw error } if (isAxiosError(error)) { const errorMessage = `isAxiosError: ${error?.response?.data ? error.response.data.code + '-' + error.response.data.message : '[UNKOWN ERROR]' + error}` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS005, baseError: error?.message }) } const errorMessage = `[${arguments.callee.name}] Uncatched Error` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS006, baseError: error?.message }) } } async getFace(faceToken) { try { if (!faceToken) throw new hfSecHerror({ message: 'Invalid faceToken parameter received', ...CODES.HFS002 }) if (faceToken.length != 24) throw new hfSecHerror({ message: 'Invalid faceToken parameter received', ...CODES.HFS002 }) const response = await requestGetCall(this.baseUrl, `${config.endpoints.xcore.getFace}/${faceToken}`) if (!response || response?.data?.code != 0) { const errorMessage = `[${arguments.callee.name}] xcore not responding [for id:${userDescription.id}]` throw new hfSecHerror({ id: userDescription.id, message: errorMessage, ...CODES.HFS004, baseErrorCode: response?.data?.code }) } return response.data } catch (error) { if (error instanceof hfSecHerror) { throw error } if (isAxiosError(error)) { const errorMessage = `isAxiosError: ${error?.response?.data ? error.response.data.code + '-' + error.response.data.message : '[UNKOWN ERROR]' + error}` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS005, baseError: error?.message }) } const errorMessage = `[${arguments.callee.name}] Uncatched Error` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS006, baseError: error?.message }) } } /** * @develop * @param {*} data * @returns */ async updateCreatedUser(data) { try { if (!data.id || !data.faceImage) return 'ERROR MISSING PARAMETERS id or faceImage' const deletedUser = await deleteUser(data) if (!deletedUser.includes('Successfully Deleted')) { return { id: data.id, error: `DEL-${deletedUser}` } } await new Promise((resolve) => setTimeout(resolve, 25)) const userDescription = { id: data.id, fullName: data.fullName, company: data.company, phone: data.phone } const xcoreUploaded = await this._faceUpload(data.faceImage, userDescription) if (xcoreUploaded.error) return { id: data.id, error: xcoreUploaded.error } const created = await baseCRUD.createNewUser({ faceImageId: String(xcoreUploaded.data.faceToken), imageIdXcore: String(xcoreUploaded.data.imageId), ...userDescription }) if (!created) { } await new Promise((resolve) => setTimeout(resolve, 25)) const xcoreGruped = await __groupFace(String(xcoreUploaded.data.faceToken)) if (xcoreGruped.error) return { id: data.id, error: xcoreGruped.error } return { id: data.id, idXcore: xcoreUploaded.data.faceToken, imageId: xcoreUploaded.data.imageId } } catch (error) { if (isAxiosError(error)) { logger.error('Is axios error') return { id: data.id, error: 'AXIOS ERROR. TRY AGAIAN' } } const errorMessage = `sendDetected Uncatched Error: ` + error.message === undefined ? error : error.message logger.error(errorMessage) return { id: data.id, error: errorMessage } } } /** * @develop * @param {*} data * @returns */ async deleteUser(imageId, faceToken = false) { try { if (!imageId && !faceToken) { throw new hfSecHerror({ message: 'No Input parameter received', ...CODES.HFS002 }) } if (!imageId) { throw new hfSecHerror({ message: 'Invalid imageId parameter received', ...CODES.HFS002 }) } if (imageId.length != 24) { throw new hfSecHerror({ message: 'Invalid imageId parameter received', ...CODES.HFS002 }) } if (faceToken) { if (faceToken.length != 24) { throw new hfSecHerror({ message: 'Invalid faceToken parameter received', ...CODES.HFS002 }) } const faceConsulted = this.getFace(faceToken) imageId = faceConsulted.data.imageId } const response = await requestCallRest(this.baseUrl, `${config.endpoints.xcore.deleteFace}/${imageId}`, 'DELETE') if (!response || response?.data?.code != 0) { const errorMessage = `[${arguments.callee.name}] xcore not responding [for id:${userDescription.id}]` throw new hfSecHerror({ id: userDescription.id, message: errorMessage, ...CODES.HFS004, baseErrorCode: response?.data?.code }) } return { imageId: imageId, message: `User ${imageId} , Successfully Deleted` } } catch (error) { if (error instanceof hfSecHerror) { throw error } if (isAxiosError(error)) { const errorMessage = `isAxiosError: ${error?.response?.data ? error.response.data.code + '-' + error.response.data.message : '[UNKOWN ERROR]' + error}` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS005, baseError: error?.message }) } const errorMessage = `[${arguments.callee.name}] Uncatched Error` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS006, baseError: error?.message }) } } async _faceUpload(faceImage, userDescription) { try { let stringDescription = JSON.stringify(userDescription) if (stringDescription.length >= 250) { // XCORE Doesnt allow too long descriptions const errorMessage = `Error, [userDescription] input too long, please send basic information` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS003 }) } const imageBuffer = Buffer.from(faceImage, 'base64') const form = new FormData() form.append('image', imageBuffer, { filename: `${userDescription.id}_face.jpg`, 'Content-Type': 'image/jpeg' }) const fixedHeader = { ...form.getHeaders(), 'Content-Length': form.getLengthSync() } const dataToBeSent = { image: imageBuffer, description: stringDescription } const response = await requestCallRest( this.baseUrl, config.endpoints.xcore.faceUpload, 'POST', dataToBeSent, fixedHeader ) if (!response || response?.data?.code != 0) { const errorMessage = `[${arguments.callee.name}] xcore not responding [for id:${userDescription.id}]` throw new hfSecHerror({ id: userDescription.id, message: errorMessage, ...CODES.HFS004, baseErrorCode: response?.data?.code }) } if (!response?.data?.data?.faceToken) { const errorMessage = `[${arguments.callee.name}] couldnt generate faceToken out of the received image ` throw new hfSecHerror({ id: userDescription.id, message: errorMessage, ...CODES.HFS004, baseErrorCode: response?.data?.code }) } return response.data } catch (error) { if (error instanceof hfSecHerror) { throw error } const errorMessage = `[${arguments.callee.name}] xcore not responding` throw new hfSecHerror({ id: userDescription.id, message: errorMessage, ...CODES.HFS006, baseError: error?.message }) } } // ---------------- TEST FUNCTIONS --------------------- async testThrows() { try { throw new hfSecHerror({ message: 'Error on device configuration', ...CODES.HFS003 }) } catch (error) { if (error instanceof hfSecHerror) { throw error } throw new hfSecHerror({ message: `XCORE Device start With Errors`, ...CODES.HFS004, baseError: error?.message }) } } // RULEEEEEEEEEEEEEEES async createGroup(groupName = false) { try { if (!groupName) { throw new hfSecHerror({ message: 'Invalid groupName parameter received', ...CODES.HFS002 }) } if (typeof groupName != 'string') { throw new hfSecHerror({ message: 'Invalid groupName parameter received', ...CODES.HFS002 }) } const dataService = { groupName } const response = await requestCallRest(this.baseUrl, config.endpoints.xcore.createGroup, 'POST', dataService) if (!response || response?.data?.code != 0) { const errorMessage = `[${arguments.callee.name}] xcore not responding [for id:${userDescription.id}]` throw new hfSecHerror({ id: userDescription.id, message: errorMessage, ...CODES.HFS004, baseErrorCode: response?.data?.code }) } return { message: `Goup ${groupName} , created succesfully` } } catch (error) { if (error instanceof hfSecHerror) { throw error } if (isAxiosError(error)) { const errorMessage = `isAxiosError: ${error?.response?.data ? error.response.data.code + '-' + error.response.data.message : '[UNKOWN ERROR]' + error}` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS005, baseError: error?.message }) } const errorMessage = `[${arguments.callee.name}] Uncatched Error` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS006, baseError: error?.message }) } } async deleteGroup(groupName = false, deleteAllFace = false) { try { if (!groupName) { throw new hfSecHerror({ message: 'Invalid groupName parameter received', ...CODES.HFS002 }) } if (typeof groupName != 'string') { throw new hfSecHerror({ message: 'Invalid groupName parameter received', ...CODES.HFS002 }) } const dataService = { deleteAllFace } const response = await requestCallRest(this.baseUrl, config.endpoints.xcore.deleteGroup, 'DELETE', dataService) if (!response || response?.data?.code != 0) { const errorMessage = `[${arguments.callee.name}] xcore not responding [for id:${userDescription.id}]` throw new hfSecHerror({ id: userDescription.id, message: errorMessage, ...CODES.HFS004, baseErrorCode: response?.data?.code }) } return { message: `Goup ${groupName} , created succesfully` } } catch (error) { if (error instanceof hfSecHerror) { throw error } if (isAxiosError(error)) { const errorMessage = `isAxiosError: ${error?.response?.data ? error.response.data.code + '-' + error.response.data.message : '[UNKOWN ERROR]' + error}` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS005, baseError: error?.message }) } const errorMessage = `[${arguments.callee.name}] Uncatched Error` throw new hfSecHerror({ message: errorMessage, ...CODES.HFS006, baseError: error?.message }) } } } module.exports = XCore