@ehrenkind/shopify-lib 0.8.2 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -212,13 +212,21 @@ var RETRYABLE_ERROR_CODES = /* @__PURE__ */ new Set([
212
212
  "UND_ERR_SOCKET",
213
213
  "UND_ERR_CONNECT_TIMEOUT",
214
214
  "UND_ERR_HEADERS_TIMEOUT",
215
- "UND_ERR_BODY_TIMEOUT"
215
+ "UND_ERR_BODY_TIMEOUT",
216
+ // Shopify GraphQL rate limiting — backoff lets the leaky bucket refill
217
+ "THROTTLED"
216
218
  ]);
217
219
  function hasRetryableCode(value) {
218
220
  if (!value || typeof value !== "object") return false;
219
221
  const code = value.code;
220
222
  return typeof code === "string" && RETRYABLE_ERROR_CODES.has(code);
221
223
  }
224
+ function isThrottledErrors(errors) {
225
+ const list = Array.isArray(errors) ? errors : [errors];
226
+ return list.some(
227
+ (e) => e?.extensions?.code === "THROTTLED"
228
+ );
229
+ }
222
230
  function isRetryableError(error) {
223
231
  if (!(error instanceof Error)) return false;
224
232
  if (hasRetryableCode(error)) return true;
@@ -306,7 +314,12 @@ async function makeRequest(query, variables, retries = 0) {
306
314
  errorMessages = JSON.stringify(errors);
307
315
  }
308
316
  logger.error("GraphQL query failed:", errorMessages);
309
- throw new Error(`GraphQL errors: ${errorMessages}`);
317
+ const graphqlError = new Error(`GraphQL errors: ${errorMessages}`);
318
+ if (isThrottledErrors(errors)) {
319
+ ;
320
+ graphqlError.code = "THROTTLED";
321
+ }
322
+ throw graphqlError;
310
323
  }
311
324
  if (!response.data) {
312
325
  throw new Error("No data in Shopify API response");