From f56a540b2f24ec9aec00570800564d32ac731ff0 Mon Sep 17 00:00:00 2001 From: Dave Date: Wed, 4 Mar 2026 12:21:29 -0500 Subject: [PATCH] release/2026-02-27 - Fix Time ticket issue, add additional logging around reynolds --- .../time-ticket-modal.component.jsx | 4 +- server/rr/rr-customers.js | 42 ++-- server/rr/rr-export-logs.js | 15 +- server/rr/rr-job-export.js | 42 ++-- server/rr/rr-log-xml.js | 63 ++++++ server/rr/rr-register-socket-events.js | 204 ++++++++++-------- server/rr/rr-service-vehicles.js | 40 ++-- 7 files changed, 278 insertions(+), 132 deletions(-) create mode 100644 server/rr/rr-log-xml.js diff --git a/client/src/components/time-ticket-modal/time-ticket-modal.component.jsx b/client/src/components/time-ticket-modal/time-ticket-modal.component.jsx index 7d6daed41..52397b90e 100644 --- a/client/src/components/time-ticket-modal/time-ticket-modal.component.jsx +++ b/client/src/components/time-ticket-modal/time-ticket-modal.component.jsx @@ -47,7 +47,7 @@ export function TimeTicketModalComponent({ } = useTreatmentsWithConfig({ attributes: {}, names: ["Enhanced_Payroll"], - splitKey: bodyshop.imexshopid + splitKey: bodyshop?.imexshopid }); const [loadLineTicketData, { loading, data: lineTicketData, refetch }] = useLazyQuery(GET_LINE_TICKET_BY_PK, { @@ -347,7 +347,7 @@ export function LaborAllocationContainer({ } = useTreatmentsWithConfig({ attributes: {}, names: ["Enhanced_Payroll"], - splitKey: bodyshop.imexshopid + splitKey: bodyshop?.imexshopid }); if (loading) return ; diff --git a/server/rr/rr-customers.js b/server/rr/rr-customers.js index 0895bf5b4..7c5fe671f 100644 --- a/server/rr/rr-customers.js +++ b/server/rr/rr-customers.js @@ -1,6 +1,7 @@ const { RRClient } = require("./lib/index.cjs"); const { getRRConfigFromBodyshop } = require("./rr-config"); const CreateRRLogEvent = require("./rr-logger-event"); +const { withRRRequestXml } = require("./rr-log-xml"); const InstanceManager = require("../utils/instanceMgr").default; /** @@ -217,14 +218,24 @@ const createRRCustomer = async ({ bodyshop, job, overrides = {}, socket }) => { try { response = await client.insertCustomer(safePayload, opts); // Very noisy; only show when log level is cranked to SILLY - CreateRRLogEvent(socket, "SILLY", "{CU} insertCustomer: raw response", { response }); + CreateRRLogEvent( + socket, + "SILLY", + "{CU} insertCustomer: raw response", + withRRRequestXml(response, { response }) + ); } catch (e) { - CreateRRLogEvent(socket, "ERROR", "RR insertCustomer transport error", { - message: e?.message, - code: e?.code, - status: e?.meta?.status || e?.status, - payload: safePayload - }); + CreateRRLogEvent( + socket, + "ERROR", + "RR insertCustomer transport error", + withRRRequestXml(e, { + message: e?.message, + code: e?.code, + status: e?.meta?.status || e?.status, + payload: safePayload + }) + ); throw e; } @@ -233,12 +244,17 @@ const createRRCustomer = async ({ bodyshop, job, overrides = {}, socket }) => { let customerNo = data?.dmsRecKey; if (!customerNo) { - CreateRRLogEvent(socket, "ERROR", "RR insertCustomer returned no dmsRecKey/custNo", { - status: trx?.status, - statusCode: trx?.statusCode, - message: trx?.message, - data - }); + CreateRRLogEvent( + socket, + "ERROR", + "RR insertCustomer returned no dmsRecKey/custNo", + withRRRequestXml(response, { + status: trx?.status, + statusCode: trx?.statusCode, + message: trx?.message, + data + }) + ); throw new Error( `RR insertCustomer returned no dmsRecKey (status=${trx?.status ?? "?"} code=${trx?.statusCode ?? "?"}${ diff --git a/server/rr/rr-export-logs.js b/server/rr/rr-export-logs.js index 184d54a4f..7dff70f6c 100644 --- a/server/rr/rr-export-logs.js +++ b/server/rr/rr-export-logs.js @@ -1,6 +1,7 @@ const { GraphQLClient } = require("graphql-request"); const queries = require("../graphql-client/queries"); const CreateRRLogEvent = require("./rr-logger-event"); +const { extractRRXmlPair } = require("./rr-log-xml"); /** Get bearer token from the socket (same approach used elsewhere) */ const getAuthToken = (socket) => @@ -178,11 +179,23 @@ const insertRRFailedExportLog = async ({ socket, jobId, job, bodyshop, error, cl const client = new GraphQLClient(endpoint, {}); client.setHeaders({ Authorization: `Bearer ${token}` }); + const { requestXml, responseXml } = extractRRXmlPair(error); + const xmlFromError = + requestXml || responseXml + ? { + ...(requestXml ? { request: requestXml } : {}), + ...(responseXml ? { response: responseXml } : {}) + } + : undefined; + const meta = buildRRExportMeta({ result, extra: { error: error?.message || String(error), - classification: classification || undefined + classification: classification || undefined, + ...(requestXml ? { requestXml } : {}), + ...(responseXml ? { responseXml } : {}), + ...(xmlFromError && !result?.xml ? { xml: xmlFromError } : {}) } }); diff --git a/server/rr/rr-job-export.js b/server/rr/rr-job-export.js index 9cc074ab6..a5248bcf2 100644 --- a/server/rr/rr-job-export.js +++ b/server/rr/rr-job-export.js @@ -1,6 +1,7 @@ const { buildRRRepairOrderPayload } = require("./rr-job-helpers"); const { buildClientAndOpts } = require("./rr-lookup"); const CreateRRLogEvent = require("./rr-logger-event"); +const { withRRRequestXml } = require("./rr-log-xml"); const { extractRrResponsibilityCenters } = require("./rr-responsibility-centers"); const CdkCalculateAllocations = require("./rr-calculate-allocations").default; const { resolveRROpCodeFromBodyshop } = require("./rr-utils"); @@ -147,10 +148,7 @@ const createMinimalRRRepairOrder = async (args) => { const response = await client.createRepairOrder(payload, finalOpts); - CreateRRLogEvent(socket, "INFO", "RR minimal Repair Order created", { - payload, - response - }); + CreateRRLogEvent(socket, "INFO", "RR minimal Repair Order created", withRRRequestXml(response, { payload, response })); const data = response?.data || null; const statusBlocks = response?.statusBlocks || {}; @@ -327,7 +325,7 @@ const updateRRRepairOrderWithFullData = async (args) => { // Without this, Reynolds won't recognize the OpCode when we send rogg operations // The rolabor section tells Reynolds "these jobs exist" even with minimal data - CreateRRLogEvent(socket, "INFO", "Sending full data for early RO (using create with roNo)", { + CreateRRLogEvent(socket, "INFO", "Preparing full data for early RO (using create with roNo)", { roNo: String(roNo), hasRolabor: !!payload.rolabor, hasRogg: !!payload.rogg, @@ -338,10 +336,18 @@ const updateRRRepairOrderWithFullData = async (args) => { // Reynolds will merge this with the existing RO header const response = await client.createRepairOrder(payload, finalOpts); - CreateRRLogEvent(socket, "INFO", "RR Repair Order full data sent", { - payload, - response - }); + CreateRRLogEvent( + socket, + "INFO", + "Sending full data for early RO (using create with roNo)", + withRRRequestXml(response, { + roNo: String(roNo), + hasRolabor: !!payload.rolabor, + hasRogg: !!payload.rogg, + payload, + response + }) + ); const data = response?.data || null; const statusBlocks = response?.statusBlocks || {}; @@ -501,10 +507,7 @@ const exportJobToRR = async (args) => { const response = await client.createRepairOrder(payload, finalOpts); - CreateRRLogEvent(socket, "INFO", "RR raw Repair Order created", { - payload, - response - }); + CreateRRLogEvent(socket, "INFO", "RR raw Repair Order created", withRRRequestXml(response, { payload, response })); const data = response?.data || null; const statusBlocks = response?.statusBlocks || {}; @@ -603,10 +606,15 @@ const finalizeRRRepairOrder = async (args) => { const rrRes = await client.updateRepairOrder(payload, finalOpts); - CreateRRLogEvent(socket, "SILLY", "RR Repair Order finalized", { - payload, - response: rrRes - }); + CreateRRLogEvent( + socket, + "SILLY", + "RR Repair Order finalized", + withRRRequestXml(rrRes, { + payload, + response: rrRes + }) + ); const data = rrRes?.data || null; const statusBlocks = rrRes?.statusBlocks || {}; diff --git a/server/rr/rr-log-xml.js b/server/rr/rr-log-xml.js new file mode 100644 index 000000000..0761d3418 --- /dev/null +++ b/server/rr/rr-log-xml.js @@ -0,0 +1,63 @@ +/** + * Extract request/response XML from RR response/result shapes. + * @param rrObj + * @returns {{requestXml: string|null, responseXml: string|null}} + */ +const extractRRXmlPair = (rrObj) => { + const xml = rrObj?.xml ?? rrObj?.meta?.xml; + + let requestXml = null; + let responseXml = null; + + if (typeof xml === "string") { + requestXml = xml; + } else { + if (typeof xml?.request === "string") requestXml = xml.request; + else if (typeof xml?.req === "string") requestXml = xml.req; + else if (typeof xml?.starXml === "string") requestXml = xml.starXml; + if (typeof xml?.response === "string") responseXml = xml.response; + } + + if (!requestXml && typeof rrObj?.requestXml === "string") requestXml = rrObj.requestXml; + if (!requestXml && typeof rrObj?.meta?.requestXml === "string") requestXml = rrObj.meta.requestXml; + if (!requestXml && typeof rrObj?.meta?.reqXml === "string") requestXml = rrObj.meta.reqXml; + if (!requestXml && typeof rrObj?.meta?.request === "string") requestXml = rrObj.meta.request; + if (!responseXml && typeof rrObj?.responseXml === "string") responseXml = rrObj.responseXml; + if (!responseXml && typeof rrObj?.meta?.responseXml === "string") responseXml = rrObj.meta.responseXml; + if (!responseXml && typeof rrObj?.meta?.resXml === "string") responseXml = rrObj.meta.resXml; + if (!responseXml && typeof rrObj?.meta?.response === "string") responseXml = rrObj.meta.response; + + // If wrapped HTTP response data contains raw XML, surface it. + if (!responseXml && typeof rrObj?.response?.data === "string") { + const xmlData = rrObj.response.data.trim(); + if (xmlData.startsWith("<")) responseXml = xmlData; + } + + // Try one level down when errors are wrapped. + if ((!requestXml || !responseXml) && rrObj?.cause && rrObj.cause !== rrObj) { + const nested = extractRRXmlPair(rrObj.cause); + if (!requestXml) requestXml = nested.requestXml; + if (!responseXml) responseXml = nested.responseXml; + } + + return { requestXml, responseXml }; +}; + +/** + * Add Reynolds request/response XML to RR log metadata when available. + * @param rrObj + * @param meta + * @returns {*} + */ +const withRRRequestXml = (rrObj, meta = {}) => { + const { requestXml, responseXml } = extractRRXmlPair(rrObj); + const xmlMeta = {}; + if (requestXml) xmlMeta.requestXml = requestXml; + if (responseXml) xmlMeta.responseXml = responseXml; + return Object.keys(xmlMeta).length ? { ...meta, ...xmlMeta } : meta; +}; + +module.exports = { + extractRRXmlPair, + withRRRequestXml +}; diff --git a/server/rr/rr-register-socket-events.js b/server/rr/rr-register-socket-events.js index bdb51580e..92db91d99 100644 --- a/server/rr/rr-register-socket-events.js +++ b/server/rr/rr-register-socket-events.js @@ -12,6 +12,7 @@ const { createRRCustomer } = require("./rr-customers"); const { ensureRRServiceVehicle } = require("./rr-service-vehicles"); const { classifyRRVendorError } = require("./rr-errors"); const { markRRExportSuccess, insertRRFailedExportLog } = require("./rr-export-logs"); +const { withRRRequestXml } = require("./rr-log-xml"); const { makeVehicleSearchPayloadFromJob, ownersFromVinBlocks, @@ -48,46 +49,6 @@ const resolveJobId = (explicit, payload, job) => explicit || payload?.jobId || j */ const resolveVin = ({ tx, job }) => tx?.jobData?.vin || job?.v_vin || null; -/** - * Extract request/response XML from RR response/result shapes. - * @param rrObj - * @returns {{requestXml: string|null, responseXml: string|null}} - */ -const extractRRXmlPair = (rrObj) => { - const xml = rrObj?.xml; - - let requestXml = null; - let responseXml = null; - - if (typeof xml === "string") { - requestXml = xml; - } else { - if (typeof xml?.request === "string") requestXml = xml.request; - else if (typeof xml?.req === "string") requestXml = xml.req; - else if (typeof xml?.starXml === "string") requestXml = xml.starXml; - if (typeof xml?.response === "string") responseXml = xml.response; - } - - if (!requestXml && typeof rrObj?.requestXml === "string") requestXml = rrObj.requestXml; - if (!responseXml && typeof rrObj?.responseXml === "string") responseXml = rrObj.responseXml; - - return { requestXml, responseXml }; -}; - -/** - * Add Reynolds request/response XML to RR log metadata when available. - * @param rrObj - * @param meta - * @returns {*} - */ -const withRRRequestXml = (rrObj, meta = {}) => { - const { requestXml, responseXml } = extractRRXmlPair(rrObj); - const xmlMeta = {}; - if (requestXml) xmlMeta.requestXml = requestXml; - if (responseXml) xmlMeta.responseXml = responseXml; - return Object.keys(xmlMeta).length ? { ...meta, ...xmlMeta } : meta; -}; - /** * Sort vehicle owners first in the list, preserving original order otherwise. * @param list @@ -279,7 +240,12 @@ const rrMultiCustomerSearch = async ({ bodyshop, job, socket, redisHelpers }) => const multiResponse = await rrCombinedSearch(bodyshop, q); - CreateRRLogEvent(socket, "SILLY", "Multi Customer Search - raw combined search", { response: multiResponse }); + CreateRRLogEvent( + socket, + "SILLY", + "Multi Customer Search - raw combined search", + withRRRequestXml(multiResponse, { response: multiResponse }) + ); if (fromVin) { const multiBlocks = Array.isArray(multiResponse?.data) ? multiResponse.data : []; @@ -300,7 +266,7 @@ const rrMultiCustomerSearch = async ({ bodyshop, job, socket, redisHelpers }) => const norm = normalizeCustomerCandidates(multiResponse, { ownersSet }); merged.push(...norm); } catch (e) { - CreateRRLogEvent(socket, "WARN", "Multi-search subquery failed", { kind: q.kind, error: e.message }); + CreateRRLogEvent(socket, "WARN", "Multi-search subquery failed", withRRRequestXml(e, { kind: q.kind, error: e.message })); } } @@ -348,7 +314,7 @@ const registerRREvents = ({ socket, redisHelpers }) => { count: decorated.length }); } catch (e) { - CreateRRLogEvent(socket, "ERROR", "RR combined lookup error", { error: e.message, jobid }); + CreateRRLogEvent(socket, "ERROR", "RR combined lookup error", withRRRequestXml(e, { error: e.message, jobid })); cb?.({ jobid, error: e.message }); } }); @@ -425,7 +391,7 @@ const registerRREvents = ({ socket, redisHelpers }) => { fromCache }); } catch (err) { - CreateRRLogEvent(socket, "ERROR", "rr-get-advisors: failed", { error: err?.message }); + CreateRRLogEvent(socket, "ERROR", "rr-get-advisors: failed", withRRRequestXml(err, { error: err?.message })); ack?.({ ok: false, error: err?.message || "get advisors failed" }); } }); @@ -496,11 +462,16 @@ const registerRREvents = ({ socket, redisHelpers }) => { anyOwner: decorated.some((c) => c.vinOwner || c.isVehicleOwner) }); } catch (error) { - CreateRRLogEvent(socket, "ERROR", `Error during RR early RO creation (prepare)`, { - error: error.message, - stack: error.stack, - jobid: rid - }); + CreateRRLogEvent( + socket, + "ERROR", + `Error during RR early RO creation (prepare)`, + withRRRequestXml(error, { + error: error.message, + stack: error.stack, + jobid: rid + }) + ); try { socket.emit("export-failed", { vendor: "rr", jobId: rid, error: error.message }); @@ -597,7 +568,12 @@ const registerRREvents = ({ socket, redisHelpers }) => { if (vehQ && vehQ.kind === "vin" && job?.v_vin) { const vinResponse = await rrCombinedSearch(bodyshop, vehQ); - CreateRRLogEvent(socket, "SILLY", `VIN owner pre-check response (early RO)`, { response: vinResponse }); + CreateRRLogEvent( + socket, + "SILLY", + `VIN owner pre-check response (early RO)`, + withRRRequestXml(vinResponse, { response: vinResponse }) + ); const vinBlocks = Array.isArray(vinResponse?.data) ? vinResponse.data : []; @@ -630,9 +606,14 @@ const registerRREvents = ({ socket, redisHelpers }) => { } } } catch (e) { - CreateRRLogEvent(socket, "WARN", `VIN owner pre-check failed; continuing with selected customer (early RO)`, { - error: e?.message - }); + CreateRRLogEvent( + socket, + "WARN", + `VIN owner pre-check failed; continuing with selected customer (early RO)`, + withRRRequestXml(e, { + error: e?.message + }) + ); } // Cache final/effective customer selection @@ -905,14 +886,19 @@ const registerRREvents = ({ socket, redisHelpers }) => { } catch (error) { const cls = classifyRRVendorError(error); - CreateRRLogEvent(socket, "ERROR", `Error during RR early RO creation (customer-selected)`, { - error: error.message, - vendorStatusCode: cls.vendorStatusCode, - code: cls.errorCode, - friendly: cls.friendlyMessage, - stack: error.stack, - jobid: rid - }); + CreateRRLogEvent( + socket, + "ERROR", + `Error during RR early RO creation (customer-selected)`, + withRRRequestXml(error, { + error: error.message, + vendorStatusCode: cls.vendorStatusCode, + code: cls.errorCode, + friendly: cls.friendlyMessage, + stack: error.stack, + jobid: rid + }) + ); try { if (!bodyshop || !job) { @@ -1097,7 +1083,28 @@ const registerRREvents = ({ socket, redisHelpers }) => { roNo: job.dms_id }); + CreateRRLogEvent( + socket, + "SILLY", + "{4.1} RR RO update response received", + withRRRequestXml(result, { + dmsRoNo: job.dms_id, + success: !!result?.success + }) + ); + if (!result?.success) { + CreateRRLogEvent( + socket, + "ERROR", + "RR Repair Order update failed", + withRRRequestXml(result, { + jobId: rid, + dmsRoNo: job.dms_id, + roStatus: result?.roStatus, + statusBlocks: result?.statusBlocks + }) + ); throw new Error(result?.roStatus?.message || "Failed to update RR Repair Order"); } @@ -1154,11 +1161,16 @@ const registerRREvents = ({ socket, redisHelpers }) => { anyOwner: decorated.some((c) => c.vinOwner || c.isVehicleOwner) }); } catch (error) { - CreateRRLogEvent(socket, "ERROR", `Error during RR export (prepare)`, { - error: error.message, - stack: error.stack, - jobid: rid - }); + CreateRRLogEvent( + socket, + "ERROR", + `Error during RR export (prepare)`, + withRRRequestXml(error, { + error: error.message, + stack: error.stack, + jobid: rid + }) + ); try { socket.emit("export-failed", { vendor: "rr", jobId: rid, error: error.message }); @@ -1220,7 +1232,12 @@ const registerRREvents = ({ socket, redisHelpers }) => { if (vehQ && vehQ.kind === "vin" && job?.v_vin) { const vinResponse = await rrCombinedSearch(bodyshop, vehQ); - CreateRRLogEvent(socket, "SILLY", `VIN owner pre-check response`, { response: vinResponse }); + CreateRRLogEvent( + socket, + "SILLY", + `VIN owner pre-check response`, + withRRRequestXml(vinResponse, { response: vinResponse }) + ); const vinBlocks = Array.isArray(vinResponse?.data) ? vinResponse.data : []; @@ -1253,9 +1270,14 @@ const registerRREvents = ({ socket, redisHelpers }) => { } } } catch (e) { - CreateRRLogEvent(socket, "WARN", `VIN owner pre-check failed; continuing with selected customer`, { - error: e?.message - }); + CreateRRLogEvent( + socket, + "WARN", + `VIN owner pre-check failed; continuing with selected customer`, + withRRRequestXml(e, { + error: e?.message + }) + ); } // Cache final/effective customer selection @@ -1532,14 +1554,19 @@ const registerRREvents = ({ socket, redisHelpers }) => { } catch (error) { const cls = classifyRRVendorError(error); - CreateRRLogEvent(socket, "ERROR", `Error during RR export (selected-customer)`, { - error: error.message, - vendorStatusCode: cls.vendorStatusCode, - code: cls.errorCode, - friendly: cls.friendlyMessage, - stack: error.stack, - jobid: rid - }); + CreateRRLogEvent( + socket, + "ERROR", + `Error during RR export (selected-customer)`, + withRRRequestXml(error, { + error: error.message, + vendorStatusCode: cls.vendorStatusCode, + code: cls.errorCode, + friendly: cls.friendlyMessage, + stack: error.stack, + jobid: rid + }) + ); try { if (!bodyshop || !job) { @@ -1707,14 +1734,19 @@ const registerRREvents = ({ socket, redisHelpers }) => { } } catch (error) { const cls = classifyRRVendorError(error); - CreateRRLogEvent(socket, "ERROR", `Error during RR finalize`, { - error: error.message, - vendorStatusCode: cls.vendorStatusCode, - code: cls.errorCode, - friendly: cls.friendlyMessage, - stack: error.stack, - jobid: rid - }); + CreateRRLogEvent( + socket, + "ERROR", + `Error during RR finalize`, + withRRRequestXml(error, { + error: error.message, + vendorStatusCode: cls.vendorStatusCode, + code: cls.errorCode, + friendly: cls.friendlyMessage, + stack: error.stack, + jobid: rid + }) + ); try { if (!bodyshop || !job) { diff --git a/server/rr/rr-service-vehicles.js b/server/rr/rr-service-vehicles.js index 597a2ea90..72c9bd559 100644 --- a/server/rr/rr-service-vehicles.js +++ b/server/rr/rr-service-vehicles.js @@ -1,5 +1,6 @@ const { buildClientAndOpts, rrCombinedSearch } = require("./rr-lookup"); const CreateRRLogEvent = require("./rr-logger-event"); +const { withRRRequestXml } = require("./rr-log-xml"); /** * Pick and normalize VIN from inputs * @param vin @@ -168,9 +169,12 @@ const ensureRRServiceVehicle = async (args = {}) => { if (bodyshop) { const combinedSearchResponse = await rrCombinedSearch(bodyshop, { kind: "vin", vin: vinStr, maxResults: 50 }); - CreateRRLogEvent(socket, "silly", "{SV} Preflight combined search by VIN: raw response", { - response: combinedSearchResponse - }); + CreateRRLogEvent( + socket, + "silly", + "{SV} Preflight combined search by VIN: raw response", + withRRRequestXml(combinedSearchResponse, { response: combinedSearchResponse }) + ); owners = ownersFromCombined(combinedSearchResponse, vinStr); } @@ -194,10 +198,15 @@ const ensureRRServiceVehicle = async (args = {}) => { } } catch (e) { // Preflight shouldn't be fatal; log and continue to insert (idempotency will still be handled) - CreateRRLogEvent(socket, "warn", "{SV} VIN preflight lookup failed; continuing to insert", { - vin: vinStr, - error: e?.message - }); + CreateRRLogEvent( + socket, + "warn", + "{SV} VIN preflight lookup failed; continuing to insert", + withRRRequestXml(e, { + vin: vinStr, + error: e?.message + }) + ); } // Vendor says: MODEL DESCRIPTION HAS MAXIMUM LENGTH OF 20 @@ -271,7 +280,7 @@ const ensureRRServiceVehicle = async (args = {}) => { try { const res = await client.insertServiceVehicle(insertPayload, insertOpts); - CreateRRLogEvent(socket, "silly", "{SV} insertServiceVehicle: raw response", { res }); + CreateRRLogEvent(socket, "silly", "{SV} insertServiceVehicle: raw response", withRRRequestXml(res, { res })); const data = res?.data ?? {}; const svId = data?.dmsRecKey || data?.svId || undefined; @@ -309,11 +318,16 @@ const ensureRRServiceVehicle = async (args = {}) => { }; } - CreateRRLogEvent(socket, "error", "{SV} insertServiceVehicle: failure", { - message: e?.message, - code: e?.code, - status: e?.meta?.status || e?.status - }); + CreateRRLogEvent( + socket, + "error", + "{SV} insertServiceVehicle: failure", + withRRRequestXml(e, { + message: e?.message, + code: e?.code, + status: e?.meta?.status || e?.status + }) + ); throw e; }