Documentation Index Fetch the complete documentation index at: https://www.commercengine.io/docs/llms.txt
Use this file to discover all available pages before exploring further.
The SDK provides consistent, type-safe error handling across all API operations with automatic recovery mechanisms and structured error responses.
The { data, error } Pattern
All SDK methods return a consistent object with data and error properties, allowing for easy, type-safe error handling.
Type-Safe Error Handling
const { data , error } = await client.catalog. getProductDetail ({ product_id_or_slug: 'product-id' });
if (data) {
// ✅ TypeScript knows data.product is a ProductDetail
console. log (data.product.name);
console. log (data.product.selling_price);
} else if (error) {
// ✅ TypeScript knows error is ApiErrorResponse
console. error (error.message);
console. error (error.code);
// Handle specific error types
switch (error.code) {
case 'NOT_FOUND' :
showProductNotFound ();
break ;
case 'VALIDATION_ERROR' :
showValidationError (error.details);
break ;
default :
showGenericError (error.message);
}
}
Error Types & Codes
The SDK provides structured error responses with consistent codes:
Automatically handled by SDK , but you can detect them:const { data , error } = await client.auth. retrieveUser ();
if (error && error.code === 'UNAUTHORIZED' ) {
// User needs to log in
redirectToLogin ();
}
Common Codes:
UNAUTHORIZED - Invalid or expired token
TOKEN_EXPIRED - Token needs refresh (handled automatically)
INVALID_CREDENTIALS - Login failed
Field-specific validation failures: const { data , error } = await client.cart. addDeleteCartItem ({ id: 'cart-id' }, {
product_id: 'invalid-product' ,
variant_id: null ,
quantity: - 1
});
if (error && error.code === 'VALIDATION_ERROR' ) {
// Access detailed field errors
console. log (error.details);
// { field: 'quantity', message: 'Must be greater than 0' }
}
Common Codes:
VALIDATION_ERROR - Field validation failed
INVALID_INPUT - Malformed request data
CONSTRAINT_VIOLATION - Business rule violation
Missing or unavailable resources: const { data , error } = await client.order. retrieveOrderDetail ( 'non-existent-order' );
if (error) {
switch (error.code) {
case 'NOT_FOUND' :
showOrderNotFound ();
break ;
case 'ACCESS_DENIED' :
showAccessDenied ();
break ;
}
}
Common Codes:
NOT_FOUND - Resource doesn’t exist
ACCESS_DENIED - Insufficient permissions
RESOURCE_CONFLICT - Conflicting operation
Connection and timeout issues: // SDK automatically retries network errors
const { data , error } = await client.catalog. listProducts ();
if (error && error.code === 'NETWORK_ERROR' ) {
// Show offline message or retry option
showNetworkError ();
}
Common Codes:
NETWORK_ERROR - Connection failed
TIMEOUT - Request timed out
UNAUTHORIZED - Authentication failed
Automatic Error Recovery
Token Refresh
The SDK automatically handles token expiry:
// This request may trigger automatic token refresh
const { data , error } = await client.customer. getCustomer ({ id: 'user-id' });
// No manual token handling needed!
if (data) {
console. log (data.customer_detail.email);
}
Authentication Recovery
The SDK automatically handles token refresh and authentication recovery:
// SDK handles token refresh transparently
const client = createStorefront ({
storeId: 'your-store-id' ,
apiKey: 'your-api-key' ,
tokenStorage: new BrowserTokenStorage () // Enables automatic token management
});
Error Handling Patterns
Component Error Boundaries
// React error boundary for SDK errors
class SDKErrorBoundary extends React . Component {
constructor ( props ) {
super (props);
this .state = { hasError: false , error: null };
}
static getDerivedStateFromError ( error ) {
return { hasError: true , error };
}
render () {
if ( this .state.hasError) {
// Handle SDK-specific errors
if ( this .state.error?.code === 'NETWORK_ERROR' ) {
return < NetworkErrorPage />;
}
return < GenericErrorPage error ={ this . state . error } />;
}
return this .props.children;
}
}
// Handle validation errors in forms
async function submitForm ( formData ) {
const { data , error } = await client.customer. updateCustomerDetail ( 'user-id' , formData);
if (error) {
if (error.code === 'VALIDATION_ERROR' ) {
// Display field-specific errors
setFieldErrors (error.details);
return ;
}
// Handle other errors
setGeneralError (error.message);
}
// Success
showSuccessMessage ();
}
Global Error Handler
// Global error handler for SDK operations
const handleSDKError = ( error : ApiErrorResponse ) => {
// Log to monitoring service
errorLogger. log (error);
// Show user-friendly messages
switch (error.code) {
case 'NETWORK_ERROR' :
toast. error ( 'Connection problem. Please check your internet.' );
break ;
case 'UNAUTHORIZED' :
toast. error ( 'Session expired. Please log in again.' );
redirectToLogin ();
break ;
case 'SERVER_ERROR' :
toast. error ( 'Server error. Please try again later.' );
break ;
default :
toast. error (error.message || 'Something went wrong.' );
}
};
// Use in SDK operations
const { data , error } = await client.catalog. listProducts ();
if (error) {
handleSDKError (error);
}
Error Monitoring
Custom Error Logging
const client = createStorefront ({
storeId: 'your-store-id' ,
apiKey: 'your-api-key' ,
debug: true ,
logger : ( level , message , data ) => {
if (level === 'error' ) {
// Send to error tracking service
Sentry. captureException ( new Error (message), {
extra: data,
tags: { source: 'storefront-sdk' }
});
}
}
});
Error Analytics
// Track error patterns
const trackError = ( error : ApiErrorResponse , context : string ) => {
analytics. track ( 'sdk_error' , {
error_code: error.code,
error_message: error.message,
context,
timestamp: new Date (). toISOString (),
user_agent: navigator.userAgent
});
};
// Usage
const { data , error } = await client.order. createOrder (orderData);
if (error) {
trackError (error, 'checkout_flow' );
}
Best Practices
Show User-Friendly Messages Avoid exposing raw API errors to users.
Log Errors for Debugging Use a monitoring service to track and analyze errors.
Implement Retries Strategically Use retries for network errors, not for validation or server errors.
Use Error Boundaries Prevent UI crashes by wrapping components in error boundaries.
Cross-References
The SDK’s error handling builds on top of the patterns described in the Storefront Guides , providing automatic recovery and type safety for a better developer experience.