feature/Reynolds-and-Reynolds-DMS-API-Integration -Expand

This commit is contained in:
Dave
2025-10-01 17:11:34 -04:00
parent 42027f0858
commit 24f017bfd2
11 changed files with 744 additions and 333 deletions

View File

@@ -1,4 +1,25 @@
// -----------------------------------------------------------------------------
// Error handling utilities for Reynolds & Reynolds (RR) API calls.
// This mirrors Fortellis/CDK error helpers so the call pipeline stays uniform.
//
// TODO:RR — Replace the heuristics in assertRrOk with the *actual* envelope and
// status semantics from the Rome RR specs. Examples in the PDFs may show:
// - <Status code="0" severity="INFO">Success</Status>
// - <Status code="123" severity="ERROR">Some message</Status>
// - or a SuccessFlag/ReturnCode element in the JSON/XML response.
// -----------------------------------------------------------------------------
class RrApiError extends Error {
/**
* @param {string} message - Human-readable message
* @param {object} opts
* @param {string} [opts.reqId] - Internal request identifier
* @param {string} [opts.url] - Target URL of the API call
* @param {string} [opts.apiName] - Which API was invoked (for context)
* @param {object} [opts.errorData] - Raw error payload from RR
* @param {number} [opts.status] - HTTP status code
* @param {string} [opts.statusText] - HTTP status text
*/
constructor(message, { reqId, url, apiName, errorData, status, statusText } = {}) {
super(message);
this.name = "RrApiError";
@@ -11,15 +32,35 @@ class RrApiError extends Error {
}
}
// Match Rome/RR envelope once you confirm it; keep this central.
/**
* Assert that an RR API response is considered "OK".
* Throws RrApiError otherwise.
*
* @param {*} data - Parsed response object from MakeRRCall
* @param {object} opts
* @param {string} opts.apiName - Which API we're checking (for error messages)
* @param {boolean} [opts.allowEmpty=false] - If true, allow null/empty results
* @returns {*} - The same data if valid
*/
function assertRrOk(data, { apiName, allowEmpty = false } = {}) {
// Example heuristicsupdate to exact envelope from the PDF:
// - successFlag === true, or
// - code === "0", or
// - !error / !errors length, etc.
if (!allowEmpty && (data == null || data.error || data.errors?.length)) {
throw new RrApiError(`${apiName} returned an error`, { errorData: data });
// TODO:RRUpdate logic to exactly match RR's success envelope.
// Possible patterns to confirm from PDFs:
// - data.Status?.code === "0"
// - data.Return?.successFlag === true
// - data.Errors is missing or empty
//
// For now, we use a simple heuristic fallback.
const hasErrors =
data == null ||
data.error ||
(Array.isArray(data.errors) && data.errors.length > 0) ||
(data.Status && data.Status.severity === "ERROR");
if (!allowEmpty && hasErrors) {
throw new RrApiError(`${apiName} returned an error`, { errorData: data, apiName });
}
return data;
}