Downloads API - Error Handling
Downloads API - Error Handling & Best Practices
Section titled “Downloads API - Error Handling & Best Practices”Learn how to handle errors gracefully and follow best practices when using the Downloads API.
HTTP Status Codes
Section titled “HTTP Status Codes”The API uses standard HTTP status codes to indicate success or failure:
Success Codes
Section titled “Success Codes”200 OK- Request successful (file download or JSON response)
Client Error Codes
Section titled “Client Error Codes”400 Bad Request- Invalid request parameters404 Not Found- No version found matching criteria429 Too Many Requests- Rate limit exceeded
Server Error Codes
Section titled “Server Error Codes”500 Internal Server Error- Server-side error occurred
Error Response Format
Section titled “Error Response Format”Error responses are returned as JSON:
{ "error": "No plugin version found for PaperMC"}Common Error Scenarios
Section titled “Common Error Scenarios”Version Not Found (404)
Section titled “Version Not Found (404)”Cause: No plugin version available for the specified server software or Java version.
Solution:
- Check if versions exist for your server software
- Try without specifying Java version
- Verify server software name spelling
- Check available versions
Rate Limit Exceeded (429)
Section titled “Rate Limit Exceeded (429)”Cause: Too many requests in a short time period.
Solution:
- Implement exponential backoff
- Reduce request frequency
- Cache responses
- Wait for rate limit reset
Invalid Parameters (400)
Section titled “Invalid Parameters (400)”Cause: Invalid or malformed request parameters.
Solution:
- Verify parameter format
- Check parameter values
- Review API documentation
- Validate inputs before sending
Error Handling Examples
Section titled “Error Handling Examples”JavaScript/TypeScript
Section titled “JavaScript/TypeScript”async function downloadPlugin(serverSoftware, javaVersion) { try { const url = `https://api.statsly.org/api/plugin-versions/download/latest/${serverSoftware}/${javaVersion}`; const response = await fetch(url);
if (!response.ok) { switch (response.status) { case 404: throw new Error('No plugin version found for your server software'); case 429: const retryAfter = response.headers.get('Retry-After'); throw new Error(`Rate limit exceeded. Retry after ${retryAfter} seconds`); case 400: const errorData = await response.json(); throw new Error(`Invalid request: ${errorData.error}`); default: throw new Error(`HTTP ${response.status}: ${response.statusText}`); } }
const blob = await response.blob(); const filename = response.headers.get('Content-Disposition')?.split('filename=')[1]?.replace(/[""]/g, '') || 'Statsly.jar';
return { success: true, filename, blob }; } catch (error) { console.error('Download failed:', error); return { success: false, error: error.message }; }}Python
Section titled “Python”import requestsfrom requests.exceptions import RequestException
def download_plugin(server_software, java_version): url = f"https://api.statsly.org/api/plugin-versions/download/latest/{server_software}/{java_version}"
try: response = requests.get(url, stream=True) response.raise_for_status()
filename = response.headers.get('Content-Disposition', '').split('filename=')[1].strip('"') or 'Statsly.jar'
with open(filename, 'wb') as f: for chunk in response.iter_content(chunk_size=8192): f.write(chunk)
return {'success': True, 'filename': filename} except requests.HTTPError as e: if e.response.status_code == 404: return {'success': False, 'error': 'No plugin version found'} elif e.response.status_code == 429: retry_after = e.response.headers.get('Retry-After', 'unknown') return {'success': False, 'error': f'Rate limit exceeded. Retry after {retry_after} seconds'} else: return {'success': False, 'error': f'HTTP {e.response.status_code}'} except RequestException as e: return {'success': False, 'error': str(e)}#!/bin/bash
download_plugin() { local server_software=$1 local java_version=$2 local output_file=$3
http_code=$(curl -s -o "$output_file" -w "%{http_code}" \ "https://api.statsly.org/api/plugin-versions/download/latest/$server_software/$java_version")
case $http_code in 200) echo "Download successful" return 0 ;; 404) echo "Error: No plugin version found" >&2 return 1 ;; 429) echo "Error: Rate limit exceeded" >&2 return 1 ;; *) echo "Error: HTTP $http_code" >&2 return 1 ;; esac}Retry Logic
Section titled “Retry Logic”Exponential Backoff
Section titled “Exponential Backoff”Implement exponential backoff for retryable errors:
async function downloadWithRetry(url, maxRetries = 3) { for (let attempt = 0; attempt < maxRetries; attempt++) { try { const response = await fetch(url);
if (response.ok) { return await response.blob(); }
if (response.status === 429) { const retryAfter = parseInt(response.headers.get('Retry-After') || '60'); const delay = Math.min(retryAfter * 1000, Math.pow(2, attempt) * 1000); await new Promise(resolve => setTimeout(resolve, delay)); continue; }
throw new Error(`HTTP ${response.status}`); } catch (error) { if (attempt === maxRetries - 1) throw error;
const delay = Math.pow(2, attempt) * 1000; await new Promise(resolve => setTimeout(resolve, delay)); } }}Best Practices
Section titled “Best Practices”Caching
Section titled “Caching”- Cache version metadata for 5-10 minutes
- Store latest version IDs to detect updates
- Implement cache invalidation strategies
- Use ETags if available
Rate Limiting
Section titled “Rate Limiting”- Respect rate limits (100 requests per 15 minutes)
- Implement exponential backoff
- Batch requests when possible
- Monitor rate limit headers
Error Handling
Section titled “Error Handling”- Always check HTTP status codes
- Handle network errors gracefully
- Provide meaningful error messages
- Log errors for debugging
- Implement retry logic for transient errors
Download Optimization
Section titled “Download Optimization”- Use specific version IDs for reproducibility
- Verify file integrity after download
- Check file size matches expected size
- Handle partial downloads
- Implement resume capability for large files
Security
Section titled “Security”- Validate server software names
- Sanitize file paths
- Verify downloaded files
- Use HTTPS only
- Check file signatures if available
Always implement proper error handling and retry logic. Cache responses when possible to reduce API calls. Verify downloaded files before using them.
Monitoring
Section titled “Monitoring”Logging
Section titled “Logging”Log important events:
- Download attempts
- Success/failure rates
- Error types and frequencies
- Rate limit hits
- Performance metrics
Alerting
Section titled “Alerting”Set up alerts for:
- Repeated download failures
- Rate limit violations
- Unexpected error codes
- Performance degradation
Support
Section titled “Support”If you encounter persistent errors:
- Open a support ticket
- Join Discord
- Check server status
- Review API documentation