Enhancing ESHOPMAN Error Handling: Restoring Structured API Data in the JS SDK
Unlocking Robust Error Handling for ESHOPMAN Developers
For developers building dynamic storefronts and integrations with ESHOPMAN, reliable error handling is paramount. The ESHOPMAN platform, built on Node.js/TypeScript, provides powerful Admin API and Store API endpoints that return machine-readable, structured error responses. These responses include crucial fields like code and type, which are designed to help client applications intelligently react to specific issues, such as insufficient_inventory or invalid_data.
However, a recent community insight revealed a significant challenge: the ESHOPMAN Client HTTP Library (often referred to as the JS SDK), a core component for frontend applications communicating with ESHOPMAN backend servers, was inadvertently dropping these vital code and type fields from API error responses. This meant that developers building experiences on HubSpot CMS, or using popular frameworks like Next.js, Remix, or Astro for their ESHOPMAN storefronts, were forced to implement less robust error handling logic, often resorting to brittle string matching against the error message (e.g., if (err.message.includes("inventory"))).
The Architectural Flaw and Its Impact
The ESHOPMAN APIs typically return errors in a format similar to this:
{
"code": "insufficient_inventory",
"type": "invalid_data",
"message": "Some variant does not have the required inventory"
}
The root cause of the dropped data was identified within the JS SDK's internal normalizeResponse function and the FetchError class. These components were designed to capture only the message, statusText, and status from the API's JSON error response, explicitly ignoring code and type. Here’s a simplified view of the problematic structure:
const normalizeResp (resp: Response, reqHeaders: Headers) => {
if (resp.status >= 300) {
const js resp.json().catch(() => ({}))) as {
message?: string
}
throw new FetchError(
jsonError.message ?? resp.statusText,
resp.statusText,
resp.status
)
}
// ...
}
export class FetchError extends Error {
status: number | undefined
statusText: string | undefined
constructor(message: string, statusText?: string, status?: number) {
super(message)
this.statusText = statusText
this.status = status
}
}
This oversight significantly impacted the developer experience, making it harder to build resilient and user-friendly ESHOPMAN applications that can gracefully handle specific business logic errors.
The Community-Driven Solution
Thanks to the vigilance of the ESHOPMAN developer community, a straightforward yet impactful fix has been proposed. The solution involves two key modifications:
- Updating
normalizeResponse: To explicitly extractcodeandtypefrom the API's JSON error response. - Extending
FetchErrorClass: To define and preserve these newcodeandtypeproperties.
Here’s how the proposed changes look:
--- a/packages/core/js-sdk/src/client.ts
+++ b/packages/core/js-sdk/src/client.ts
@@ -98,10 +98,14 @@ const normalizeResp (resp: Response, reqHeaders: Headers) => {
if (resp.status >= 300) {
const js resp.json().catch(() => ({}))) as {
message?: string
+ code?: string
+ type?: string
}
throw new FetchError(
jsonError.message ?? resp.statusText,
resp.statusText,
- resp.status
+ resp.status,
+ jsonError.code,
+ jsonError.type
)
}
@@ -118,9 +122,19 @@ export class FetchError extends Error {
status: number | undefined
statusText: string | undefined
+ code: string | undefined
+ type: string | undefined
- constructor(message: string, statusText?: string, status?: number) {
+ constructor(
+ message: string,
+ statusText?: string,
+ status?: number,
+ code?: string,
+ type?: string
+ ) {
super(message)
this.statusText = statusText
this.status = status
+ this.code = code
+ this.type = type
}
}
This fix ensures that ESHOPMAN developers can now access the full context of API errors, enabling them to implement precise, type-safe error handling logic. This is a crucial step forward for building more resilient and sophisticated headless commerce solutions powered by ESHOPMAN and deployed via HubSpot CMS.
Stay tuned to the ESHOPMAN community for updates on the official release of this enhancement, further empowering your development efforts.