UNPKG

@eldev/business-central-api

Version:

A Dynamics 365 Business Central client for TypeScript

120 lines 4.33 kB
import { categorizeError, } from "./categorize.js"; function parseErrorResponse(data) { const response = data; if (!response.error?.code || !response.error?.message) { throw new Error("Invalid BC error response format"); } return { code: response.error.code, message: response.error.message, }; } export class BCError extends Error { category; httpStatus; retryStrategy; timestamp; correlationId; validationDetails; serverError; responseData; cause; constructor(message, category, retryStrategy, httpStatus) { super(message); this.name = "BCError"; this.category = category; this.retryStrategy = retryStrategy; this.httpStatus = httpStatus; this.timestamp = new Date(); if (Error.captureStackTrace) { Error.captureStackTrace(this, BCError); } } isRetryable() { return this.retryStrategy !== "NO_RETRY"; } isSchemaMismatch() { return this.category === "SCHEMA_MISMATCH"; } hasValidationDetails() { return Boolean(this.validationDetails?.length); } getValidationFields() { return this.validationDetails?.map((detail) => detail.path) || []; } toLogObject() { return { name: this.name, message: this.message, category: this.category, httpStatus: this.httpStatus, retryStrategy: this.retryStrategy, correlationId: this.correlationId, timestamp: this.timestamp.toISOString(), validationDetails: this.validationDetails, validationCount: this.validationDetails?.length, responseData: this.responseData, serverError: this.serverError, }; } toSpanAttributes() { return { "bc.error.category": this.category, "bc.error.retryable": this.isRetryable(), "bc.request.correlation_id": this.correlationId || "", }; } static fromHttpResponse(status, data, correlationId) { let serverError; try { serverError = parseErrorResponse(data); } catch { return BCError.fromUnexpectedResponse(data, status, correlationId); } const { category, retryStrategy } = categorizeError(serverError.code); const bcError = new BCError(serverError.message, category, retryStrategy, status); if (correlationId) bcError.correlationId = correlationId; bcError.serverError = serverError; return bcError; } static fromSchemaValidation(issues, httpStatus = 200) { const bcError = new BCError("Schema validation failed. The provided schema does not match Business Central's response format.", "SCHEMA_MISMATCH", "NO_RETRY", httpStatus); bcError.validationDetails = issues; return bcError; } static fromUnexpectedResponse(data, httpStatus, correlationId, cause) { const bcError = new BCError("Business Central returned an unexpected response format", "UNEXPECTED_RESPONSE", "NO_RETRY", httpStatus); if (correlationId) bcError.correlationId = correlationId; bcError.responseData = data; bcError.cause = cause; return bcError; } static fromGetToken(err) { let message = "Failed to retrieve authentication token."; let cause = new Error(message); if (typeof err === "string") { message = `${message}: ${err}`; cause = new Error(err); } if (err instanceof Error) { message = `${message}: ${err.message}`; cause = err; } const bcError = new BCError(message, "AUTHENTICATION", "REFRESH_TOKEN", 401); bcError.cause = cause; return bcError; } static fromNetworkError(networkError) { const nodeError = networkError; const errorMessage = nodeError.code ? `Network error (${nodeError.code}): ${networkError.message}` : `Network error: ${networkError.message}`; const bcError = new BCError(errorMessage, "NETWORK_ERROR", "EXPONENTIAL_BACKOFF", 0); bcError.cause = networkError; return bcError; } } //# sourceMappingURL=error.js.map