Error Handling
Comprehensive guide to handling errors gracefully and ensuring smooth ad experiences.
âšī¸ Why Error Handling Matters: Ads can fail for many reasons (network issues, no fill, VAST errors, etc.). Proper error handling ensures your app remains stable and provides fallback options for users.
Error Callback
The onError callback is triggered whenever an error occurs during ad loading or playback:
JavaScript
RewardedAd.init({
appId: "YOUR_APP_ID",
apiKey: "YOUR_API_KEY",
userId: "user_123",
onError: function(error) {
console.error('â Ad Error:', error.message);
console.error('Error Code:', error.code);
console.error('Details:', error.details);
// Handle error appropriately
handleAdError(error);
}
});
Error Object Structure
TypeScript
{
code: string, // Error code (e.g., "NETWORK_ERROR")
message: string, // Human-readable error message
details: object, // Additional error context
timestamp: number // When error occurred
}
Common Error Codes
| Error Code | Description | Common Causes |
|---|---|---|
NETWORK_ERROR |
Network request failed | No internet, timeout, DNS failure |
NO_FILL |
No ads available | Low inventory, targeting mismatch |
INVALID_CONFIG |
SDK configuration error | Missing appId, apiKey, or userId |
RATE_LIMIT |
Frequency cap exceeded | User hit hourly/daily limits |
VAST_ERROR |
VAST XML parsing failed | Malformed VAST, unsupported format |
MEDIA_ERROR |
Video playback failed | Unsupported format, DRM issues |
TIMEOUT |
Request timed out | Slow network, server issues |
VAST Error Codes
For VAST ads, additional IAB standard error codes are provided:
| Code | Description | Category |
|---|---|---|
| 100 | XML parsing error | VAST Structure |
| 101 | VAST schema validation error | VAST Structure |
| 102 | VAST version not supported | VAST Structure |
| 300 | General wrapper error | VAST Wrapper |
| 400 | General linear error | Video |
| 401 | File not found | Video |
| 402 | Timeout of media file | Video |
| 403 | Unsupported media type | Video |
| 900 | Undefined error | General |
Error Handling Strategies
1. Basic Error Handler
JavaScript
function handleAdError(error) {
// Log for debugging
console.error('Ad Error:', error.code, error.message);
// Show user-friendly message
const messages = {
'NETWORK_ERROR': 'Connection issue. Please check your internet.',
'NO_FILL': 'No ads available right now. Try again later!',
'RATE_LIMIT': 'You\'ve watched the maximum ads for now.',
'VAST_ERROR': 'Ad format not supported.',
'MEDIA_ERROR': 'Video could not be played.',
'TIMEOUT': 'Request timed out. Please try again.'
};
const message = messages[error.code] || 'Something went wrong. Please try again.';
showNotification(message);
// Resume game if it was paused
resumeGame();
}
2. Retry Logic
JavaScript
let retryCount = 0;
const MAX_RETRIES = 2;
function showAdWithRetry() {
RewardedAd.showAd({
rewardPreview: '100 coins',
onError: function(error) {
if (error.code === 'NETWORK_ERROR' && retryCount < MAX_RETRIES) {
retryCount++;
console.log(`Retrying... (${retryCount}/${MAX_RETRIES})`);
// Retry after delay
setTimeout(() => {
showAdWithRetry();
}, 2000);
} else {
// Max retries reached or non-retryable error
retryCount = 0;
handleAdError(error);
}
},
onReward: function() {
retryCount = 0; // Reset on success
grantCoins(100);
}
});
}
3. Fallback Options
JavaScript
function tryShowAd() {
RewardedAd.showAd({
rewardPreview: '100 coins',
onError: function(error) {
console.error('Ad failed:', error.code);
// Offer alternative reward methods
showFallbackOptions([
{
label: 'Complete a quest',
action: () => showQuests(),
icon: 'đ¯'
},
{
label: 'Invite a friend',
action: () => showInviteScreen(),
icon: 'đĨ'
},
{
label: 'Purchase coins',
action: () => showStore(),
icon: 'đ°'
}
]);
},
onReward: function() {
grantCoins(100);
}
});
}
4. Error Analytics
JavaScript
class ErrorTracker {
constructor() {
this.errors = [];
}
track(error) {
this.errors.push({
code: error.code,
message: error.message,
timestamp: Date.now()
});
// Log to your analytics service
this.sendToAnalytics(error);
// Check error rate
this.checkErrorRate();
}
sendToAnalytics(error) {
// Send to your analytics platform
if (window.gtag) {
gtag('event', 'ad_error', {
error_code: error.code,
error_message: error.message
});
}
}
checkErrorRate() {
// Last 10 attempts
const recent = this.errors.slice(-10);
const errorRate = recent.length / 10;
if (errorRate > 0.5) {
console.warn('â ī¸ High error rate detected:', errorRate);
// Maybe disable ads temporarily
}
}
getReport() {
const errorCounts = {};
this.errors.forEach(e => {
errorCounts[e.code] = (errorCounts[e.code] || 0) + 1;
});
console.log('Error Report:', errorCounts);
return errorCounts;
}
}
const errorTracker = new ErrorTracker();
RewardedAd.init({
// ...config
onError: function(error) {
errorTracker.track(error);
handleAdError(error);
}
});
Complete Error Handler
JavaScript
class AdErrorHandler {
constructor() {
this.retryAttempts = 0;
this.maxRetries = 2;
this.errorLog = [];
}
handle(error) {
// Log error
this.logError(error);
// Handle based on error type
switch (error.code) {
case 'NETWORK_ERROR':
return this.handleNetworkError(error);
case 'NO_FILL':
return this.handleNoFill(error);
case 'RATE_LIMIT':
return this.handleRateLimit(error);
case 'VAST_ERROR':
case 'MEDIA_ERROR':
return this.handleMediaError(error);
case 'INVALID_CONFIG':
return this.handleConfigError(error);
default:
return this.handleUnknownError(error);
}
}
handleNetworkError(error) {
if (this.retryAttempts < this.maxRetries) {
this.retryAttempts++;
console.log(`Network error, retrying... (${this.retryAttempts}/${this.maxRetries})`);
setTimeout(() => {
RewardedAd.showAd();
}, 2000);
} else {
this.showMessage('Connection issue. Please check your internet and try again.');
this.retryAttempts = 0;
}
}
handleNoFill(error) {
this.showMessage('No ads available right now. Try again in a moment!');
this.showFallbackOptions();
}
handleRateLimit(error) {
const cooldown = RewardedAd.getCooldownRemaining();
if (cooldown > 0) {
this.showMessage(`Please wait ${cooldown} seconds before the next ad.`);
} else {
this.showMessage('You\'ve reached the ad limit. Try again later!');
}
}
handleMediaError(error) {
this.showMessage('Ad format not supported. Trying next ad...');
// SDK will automatically try next ad in mediation waterfall
}
handleConfigError(error) {
console.error('â ī¸ SDK Configuration Error:', error.message);
this.showMessage('App configuration error. Please contact support.');
// This is a critical error - log to error tracking service
}
handleUnknownError(error) {
console.error('Unknown error:', error);
this.showMessage('Something went wrong. Please try again.');
}
logError(error) {
this.errorLog.push({
code: error.code,
message: error.message,
timestamp: new Date().toISOString()
});
// Send to error tracking service
if (window.Sentry) {
Sentry.captureException(new Error(`Ad Error: ${error.code}`), {
extra: error
});
}
}
showMessage(text) {
alert(text); // Replace with your notification system
}
showFallbackOptions() {
// Show alternative ways to earn rewards
console.log('Showing fallback options...');
}
reset() {
this.retryAttempts = 0;
}
getErrorReport() {
return this.errorLog;
}
}
// Usage
const errorHandler = new AdErrorHandler();
RewardedAd.init({
appId: "YOUR_APP_ID",
apiKey: "YOUR_API_KEY",
userId: "user_123",
onError: function(error) {
errorHandler.handle(error);
},
onReward: function(reward) {
errorHandler.reset(); // Reset retry count on success
grantCoins(100);
},
onClose: function() {
resumeGame();
}
});
Best Practices
â
DO:
- Always implement
onErrorcallback - Show user-friendly error messages
- Log errors to analytics/monitoring service
- Offer fallback options when ads fail
- Retry network errors (max 2-3 times)
- Resume game after errors
- Test error scenarios during development
â ī¸ DON'T:
- Show technical error messages to users
- Retry indefinitely (max 2-3 attempts)
- Ignore errors silently
- Leave game in broken state after errors
- Retry rate limit errors
- Expose sensitive error details in production
Testing Error Scenarios
Simulate Errors in Development
JavaScript
// Enable debug mode
RewardedAd.enableDebug();
// Test different error scenarios
function testErrors() {
// 1. Test network error (disable internet)
console.log('Test: Disable internet and call showAd()');
// 2. Test no fill (use invalid app ID)
console.log('Test: Use invalid appId');
// 3. Test rate limit (show 11 ads in an hour)
console.log('Test: Show ads rapidly');
// 4. Test VAST error (use malformed VAST URL)
console.log('Test: Use invalid VAST tag');
}
// Monitor all errors
let errorCount = 0;
RewardedAd.init({
// ...config
onError: function(error) {
errorCount++;
console.error(`Error #${errorCount}:`, error.code, error.message);
}
});
Error Recovery Checklist
â
Error Recovery Checklist:
- âī¸ Error logged to console/analytics
- âī¸ User shown friendly message
- âī¸ Game/app resumed (if paused)
- âī¸ Fallback options offered (if applicable)
- âī¸ Retry attempted (for network errors)
- âī¸ UI state reset to normal