SitecoreAI Connector
Developer Integration
Error Handling

Error Handling

Learn how SDK components handle errors gracefully without breaking your application.

Graceful Degradation

All SDK components are designed to fail gracefully and never throw exceptions that would break your application.

Null or Undefined Assets

When no asset is provided, components return null (nothing rendered):

<BynderDamImage asset={null} /> 
{/* Renders nothing */}
 
<BynderDamLink asset={undefined}>Click me</BynderDamLink> 
{/* Renders nothing */}
 
<BynderDamVideo asset={null} />
{/* Renders nothing */}

Use Case: Safely render components even when data hasn't loaded yet or is missing.

Invalid Asset Structure

When the asset structure is invalid (empty assets array or missing required fields), components render error text that can be styled:

const invalidAsset = {
  type: 'Assets',
  assets: [], // Empty array
  file: null,
  overrideAltText: null,
};
 
<BynderDamImage 
  asset={invalidAsset}
  className="text-red-600 font-bold bg-red-100 px-4 py-2 rounded"
/>
{/* Renders: "Invalid asset data" with custom styling */}

Styled Error Messages

Error messages respect the className prop, allowing you to style them consistently with your design system:

<BynderDamVideo
  asset={invalidAsset}
  className="text-purple-600 italic bg-purple-50 p-3 rounded border border-purple-300"
/>
{/* Renders: "Invalid video data" with custom styling */}

Error Messages Reference

ComponentNull/Undefined BehaviorInvalid Data Message
BynderDamImageReturns null"Invalid asset data"
BynderDamNextImageReturns null"Invalid asset data"
BynderDamLinkReturns null"Invalid asset data"
BynderDamVideoReturns null"Invalid video data"

Error Handling Patterns

With Loading States

function AssetDisplay({ assetData }) {
  const [asset, setAsset] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
 
  useEffect(() => {
    if (!assetData) {
      setLoading(false);
      return;
    }
 
    try {
      const parsed = JSON.parse(assetData);
      setAsset(parsed);
    } catch (e) {
      setError('Failed to parse asset data');
    } finally {
      setLoading(false);
    }
  }, [assetData]);
 
  if (loading) {
    return <div className="spinner">Loading...</div>;
  }
 
  if (error) {
    return <div className="text-red-600">{error}</div>;
  }
 
  return (
    <BynderDamImage
      asset={asset}
      alt="Asset"
      className="w-full rounded-lg"
    />
  );
}

With Fallback UI

function SafeImage({ asset, fallback = '/placeholder.jpg' }) {
  if (!asset?.assets?.[0]) {
    return <img src={fallback} alt="Placeholder" />;
  }
 
  return (
    <BynderDamImage
      asset={asset}
      alt="Asset"
      onError={(e) => {
        e.target.src = fallback;
      }}
    />
  );
}

With Error Boundaries

import { ErrorBoundary } from 'react-error-boundary';
 
function FallbackComponent({ error }) {
  return (
    <div className="text-red-600 p-4 border border-red-300 rounded">
      <h3>Something went wrong:</h3>
      <pre>{error.message}</pre>
    </div>
  );
}
 
function App() {
  return (
    <ErrorBoundary FallbackComponent={FallbackComponent}>
      <BynderDamImage asset={asset} alt="Product" />
    </ErrorBoundary>
  );
}

Defensive Data Parsing

function parseAssetSafely(assetData: string) {
  if (!assetData || typeof assetData !== 'string') {
    return null;
  }
 
  try {
    const parsed = JSON.parse(assetData);
    
    // Validate structure
    if (!parsed?.assets || !Array.isArray(parsed.assets)) {
      console.warn('Invalid asset structure:', parsed);
      return null;
    }
 
    return parsed;
  } catch (error) {
    console.error('Failed to parse asset data:', error);
    return null;
  }
}
 
// Usage
function MyComponent({ assetData }) {
  const asset = parseAssetSafely(assetData);
  return <BynderDamImage asset={asset} alt="Safe asset" />;
}

TypeScript Type Guards

import type { BynderAssetResponse } from '@neworange/bynder-dam-connector-sitecoreai-sdk';
 
function isValidAsset(asset: unknown): asset is BynderAssetResponse {
  if (!asset || typeof asset !== 'object') return false;
  
  const a = asset as BynderAssetResponse;
  return (
    a.type === 'Assets' &&
    Array.isArray(a.assets) &&
    a.assets.length > 0
  );
}
 
// Usage
function SafeComponent({ asset }: { asset: unknown }) {
  if (!isValidAsset(asset)) {
    return <div>Invalid asset data</div>;
  }
 
  return <BynderDamImage asset={asset} alt="Valid asset" />;
}

Logging and Monitoring

Track Rendering Errors

function MonitoredImage({ asset, alt }) {
  const handleError = (error) => {
    console.error('Image failed to load:', {
      asset: asset?.assets?.[0]?.id,
      error: error.message,
    });
    
    // Send to monitoring service
    analytics.track('image_load_error', {
      assetId: asset?.assets?.[0]?.id,
    });
  };
 
  return (
    <BynderDamImage
      asset={asset}
      alt={alt}
      onError={handleError}
    />
  );
}

Debug Mode

function DebugAssetComponent({ asset, debug = false }) {
  if (debug) {
    console.log('Asset data:', asset);
    console.log('Has assets:', asset?.assets?.length);
    console.log('First asset:', asset?.assets?.[0]);
  }
 
  return <BynderDamImage asset={asset} alt="Debug asset" />;
}

Error Handling Best Practices

✅ Do's

  • Always check for null/undefined before rendering
  • Use optional chaining when accessing nested properties
  • Provide fallback UI for better user experience
  • Log errors for debugging and monitoring
  • Validate data structure when parsing JSON strings
  • Use TypeScript type guards for runtime validation
  • Style error messages consistently with your design system

❌ Don'ts

  • Don't assume data is always valid - always validate
  • Don't throw custom errors - components already handle errors
  • Don't ignore console warnings - they indicate data issues
  • Don't skip null checks - always handle missing data
  • Don't use try-catch around components - they don't throw

Summary

The SDK's error handling approach ensures:

  1. No exceptions thrown - Components never break your app
  2. Graceful degradation - Invalid data renders error text, not nothing
  3. Styleable errors - Error messages can be styled with className
  4. Consistent behavior - All components handle errors the same way
  5. Developer-friendly - Clear error messages for debugging

This defensive approach means you can confidently use SDK components knowing they won't cause runtime errors or break your application.