Skip to content

Error Handling Examples

This page demonstrates best practices for handling errors and edge cases when using the Urban Sky SDK.

Basic Error Handling

JavaScript

javascript
// Load the SDK
const response = await fetch('https://sdk.atmosys.com/runtime/js/current/loader.js')
eval(await response.text())

const sdk = await UrbanSkySDK.init({
  apiToken: 'your-api-token-here',
  debug: true
})

// Handle connection errors
sdk.on('error', (error) => {
  console.error('SDK Error:', error)
  
  switch (error.code) {
    case 'AUTH_INVALID_TOKEN':
      console.error('❌ Invalid API token')
      // Stop trying to reconnect
      break
      
    case 'AUTH_INSUFFICIENT_PERMISSIONS':
      console.error('❌ Token lacks SDK permissions')
      // Check token permissions in dashboard
      break
      
    case 'CONNECTION_FAILED':
      console.error('❌ Connection failed - will retry')
      // SDK will auto-retry
      break
      
    case 'SERVICE_UNAVAILABLE':
      console.error('❌ Service temporarily unavailable')
      // Implement exponential backoff
      break
      
    default:
      console.error('❌ Unknown error:', error.message)
  }
})

// Handle connection state changes
sdk.on('connected', () => {
  console.log('✅ Connected to Urban Sky')
})

sdk.on('disconnected', () => {
  console.log('⚠️ Disconnected from Urban Sky')
})

// Connect with error handling
try {
  await sdk.connect()
} catch (error) {
  console.error('Failed to connect:', error)
  // Handle initial connection failure
}

Python

python
import asyncio
import logging
import requests

# Load the SDK
exec(requests.get('https://sdk.atmosys.com/runtime/py/current/loader.py').text)

# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

async def main():
    # Initialize and connect
    sdk = await UrbanSkySDK.init({
        'apiToken': 'your-api-token-here'
    })
    
    # Error event handler
    def on_error(error):
        if isinstance(error, dict):
            error_code = error.get('error', 'UNKNOWN')
            error_message = error.get('message', str(error))
        else:
            error_code = 'UNKNOWN'
            error_message = str(error)
            
        logger.error(f"SDK Error: {error_code} - {error_message}")
        
        if error_code == 'AUTH_INVALID_TOKEN':
            logger.error("❌ Invalid API token")
            
        elif error_code == 'AUTH_INSUFFICIENT_PERMISSIONS':
            logger.error("❌ Token lacks SDK permissions")
            
        elif error_code == 'CONNECTION_FAILED':
            logger.error("❌ Connection failed - will retry")
            # SDK will auto-retry
            
        elif error_code == 'SERVICE_UNAVAILABLE':
            logger.error("❌ Service temporarily unavailable")
            
        else:
            logger.error(f"❌ Unknown error: {error_message}")
    
    # Connection state handlers
    def on_connected():
        logger.info("✅ Connected to Urban Sky")
    
    def on_disconnected():
        logger.warning("⚠️ Disconnected from Urban Sky")
    
    # Register event handlers
    sdk.on('error', on_error)
    sdk.on('connected', on_connected)
    sdk.on('disconnected', on_disconnected)

asyncio.run(main())

Simple Retry Logic

For basic retry functionality when connections fail:

javascript
async function initializeWithRetry(config, maxAttempts = 3) {
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
    try {
      const sdk = await UrbanSkySDK.init(config)
      console.log('✅ Connected successfully')
      return sdk
    } catch (error) {
      console.error(`Attempt ${attempt} failed: ${error.message}`)
      
      // Don't retry on authentication errors
      if (error.code === 'AUTH_INVALID_TOKEN' || error.code === 'AUTH_INSUFFICIENT_PERMISSIONS') {
        console.error('❌ Authentication failed - not retrying')
        throw error
      }
      
      if (attempt < maxAttempts) {
        const delay = attempt * 2000 // Simple backoff: 2s, 4s, 6s
        console.log(`Retrying in ${delay}ms...`)
        await new Promise(resolve => setTimeout(resolve, delay))
      }
    }
  }
  
  console.error('❌ All connection attempts failed')
  return null
}

// Usage
const sdk = await initializeWithRetry({ apiToken: 'your-token' })
if (!sdk) {
  console.error('Unable to establish connection')
}

Handling Data Processing Errors

Implement error boundaries for data processing:

javascript
sdk.on('balloon:update', (update) => {
  try {
    // Process update
    processUpdate(update)
  } catch (error) {
    console.error('Error processing update:', error)
    // Log error but don't crash the application
    logError(error, update)
  }
})

function processUpdate(update) {
  // Validate data
  if (!update.balloonId || !update.devices) {
    throw new Error('Invalid update structure')
  }
  
  // Process each device safely
  update.devices.forEach(device => {
    try {
      processDevice(device)
    } catch (error) {
      console.error(`Error processing device ${device.deviceId}:`, error)
    }
  })
}
python
def on_balloon_update(update):
    try:
        # Process update
        process_update(update)
    except Exception as error:
        print(f"Error processing update: {error}")
        # Log error but don't crash the application
        log_error(error, update)

def process_update(update):
    # Validate data
    if 'balloon_id' not in update or 'devices' not in update:
        raise ValueError("Invalid update structure")
    
    # Process each device safely
    for device in update['devices']:
        try:
            process_device(device)
        except Exception as error:
            print(f"Error processing device {device['device_id']}: {error}")

sdk.on('balloon:update', on_balloon_update)

Best Practices

  1. Always implement error handlers - Don't let errors crash your application
  2. Log errors appropriately - Include context for debugging
  3. Use the SDK's automatic reconnection - Don't implement your own unless necessary
  4. Handle authentication errors differently - These require user action
  5. Implement data validation - Verify data structure before processing

Getting Help

If you encounter persistent errors:

  1. Check the error code and message
  2. Verify your API token is valid
  3. Ensure you have a stable internet connection
  4. Contact Urban Sky support at support@atmosys.com with:
    • Your organization name
    • The error code and message
    • When the error occurred
    • Any relevant context about what you were trying to do

Next Steps