UNPKG

nav-connect

Version:

Nav Online Invoice connection module

75 lines 3.01 kB
import { XsdSchemaName, buildApiRequestXml, xmlParser, XmlValidationError } from "nav-osa-core"; import { NavApiError, NavApiHttpError, NavApiResponseError, NavApiTimeoutError, NavXmlValidationError, } from "./errors.js"; const TIMEOUT_ERROR_CODES = new Set(["ECONNABORTED", "ETIMEDOUT"]); function toNavApiResponseError(result, httpStatus, technicalValidationMessages) { return new NavApiResponseError({ funcCode: result.funcCode, errorCode: result.errorCode, message: result.message, httpStatus, technicalValidationMessages, }); } function checkResponseResult(result) { if (!result) return; if (result.funcCode === "ERROR") { throw toNavApiResponseError(result); } } function throwIfGeneralError(parsed, httpStatus) { const generalError = parsed.GeneralErrorResponse; if (generalError?.result) { throw toNavApiResponseError(generalError.result, httpStatus, generalError.technicalValidationMessages); } } export async function handleAxiosError(error, timeoutMs) { if (error.code !== undefined && TIMEOUT_ERROR_CODES.has(error.code)) { throw new NavApiTimeoutError(timeoutMs); } const status = error.response?.status; const statusText = error.response?.statusText; const rawBody = typeof error.response?.data === "string" ? error.response.data : undefined; if (rawBody) { let parsed; try { parsed = await xmlParser(rawBody, XsdSchemaName.InvoiceApi, { validate: false }); } catch (parseErr) { if (parseErr instanceof XmlValidationError) { throw new NavApiHttpError(status ?? 0, statusText, rawBody); } throw new NavApiHttpError(status ?? 0, statusText, rawBody, parseErr); } throwIfGeneralError(parsed, status ?? 0); } throw new NavApiHttpError(status ?? 0, statusText, rawBody); } export async function parseApiResponse(responseXml, rootName) { const parsed = await xmlParser(responseXml, XsdSchemaName.InvoiceApi, { validate: false, }); // Nav always answers with the "<RequestType minus Request>Response" // root element; anything else means we cannot interpret the reply. // Functional errors arrive as GeneralErrorResponse with HTTP 200, so // that envelope must be checked before giving up on the root element. const data = parsed[rootName]; if (!data) { throwIfGeneralError(parsed, 200); throw new NavApiError(`Unexpected NAV response: missing '${rootName}' root element`); } checkResponseResult(data.result); return data; } export async function buildRequestOrThrow(requestType, reqObj) { try { return await buildApiRequestXml(requestType, reqObj); } catch (error) { if (error instanceof XmlValidationError) { throw new NavXmlValidationError(requestType, error.errors); } throw error; } } //# sourceMappingURL=errorMapping.js.map