Widget error handling allows you to gracefully manage situations where widgets encounter problems during loading or runtime. With proper error handling, you can:
The error handling system provides multiple approaches: silent mode for production environments, the onTrack callback for custom error handling logic, and visual error indicators for development and debugging.
This tutorial is for developers and integrators who are implementing Sportradar widgets and need to handle potential widget errors effectively. Understanding error handling is essential for creating production-ready integrations that gracefully handle failures.
In this tutorial you will learn:
silent property to suppress error messages in productiononTrack callbackIn order to complete this tutorial you will need:
Before implementing error handling, it's important to understand the types of errors that can occur and what causes them.
Sportradar widgets can encounter several types of errors, each with different causes and solutions:
These errors occur when a widget is missing required parameters or has invalid configuration:
matchId, seasonId, tournamentId, or other required parametersCommon causes:
These errors occur when valid configuration exists but data is not available:
Common causes:
These errors occur when there are issues with widget licensing:
Common causes:
For detailed information about licensing errors and how to resolve them, see the Licensing page.
Unexpected errors that don't fall into the above categories:
If you encounter this type of error, contact support with details about your configuration and any error messages in the browser console.
There are two main approaches to handling widget errors: using the silent property for simple error suppression, or implementing custom logic with the onTrack callback for more sophisticated error handling.
The silent property is the simplest way to prevent error messages from being displayed to end users. When set to true, the widget will not render error icons or messages, keeping your page clean even when errors occur.
Use silent: true in production environments to ensure end users never see technical error messages. Use silent: false (the default) during development to help identify and fix issues.
Example:
SIR('addWidget', '#widget-container', 'match.lmtPlus', {
matchId: 12345678,
silent: true // Suppress error display
});When to use silent mode:
Limitations:
The onTrack callback provides fine-grained control over widget behavior by allowing you to execute custom code when specific events occur, including errors. This approach enables conditional display, fallback content, and advanced error recovery strategies.
The onTrack function receives two parameters:
| Parameter | Type | Description |
|---|---|---|
eventType | string | The type of event that occurred: 'data_change', 'odds_click', 'social_share', or 'license_error' |
data | object | Event-specific data, including an error property when errors occur |
When to use onTrack:
For detailed information about onTrack events and parameters, see the onTrack documentation.
Let's implement a complete solution that loads a widget conditionally and only displays a toggle button if the widget loads successfully without errors.
<!DOCTYPE html>
<html lang="en">
<head>
<title>Widget Error Handling Demo</title>
<style>
#page-content {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
</style>
</head>
<body>
<!-- Main page content area -->
<div id="page-content">
<button id="toggle-button" style="display: none">
Toggle Widget Display
</button>
</div>
<!-- Hidden loading area for widget -->
<div id="loading-area" style="display: none">
<div id="widget-container" class="sr-widget"></div>
</div>
<script>
// Get DOM elements
const loadingArea = document.getElementById('loading-area');
const pageContent = document.getElementById('page-content');
const widget = document.getElementById('widget-container');
const toggleButton = document.getElementById('toggle-button');
// Initialize widgets framework
(function(a,b,c,d,e,f,g,h,i){a[e]||(i=a[e]=function(){
(a[e].q=a[e].q||[]).push(arguments)},i.l=1*new Date,i.o=f,
g=b.createElement(c),h=b.getElementsByTagName(c)[0],
g.async=1,g.src=d,g.setAttribute("n",e),
h.parentNode.insertBefore(g,h)
)})(window,document,"script",
"https://widgets.sir.sportradar.com/sportradar/widgetloader",
"SIR", {
language: "en",
theme: false
}
);
// Error handling callback
const onTrack = (eventType, data) => {
if (eventType === 'data_change') {
if (!data.error) {
// Widget loaded successfully
loadingArea.removeChild(widget);
pageContent.appendChild(widget);
toggleButton.style.display = 'block';
} else {
// Widget encountered an error
console.error('Widget error:', data.error);
}
}
};
// Toggle widget visibility
const toggleWidget = () => {
const isHidden = widget.style.display === 'none';
widget.style.display = isHidden ? 'block' : 'none';
};
toggleButton.onclick = toggleWidget;
// Load widget with error handling
SIR("addWidget", "#widget-container", "match.scoreboard", {
matchId: 43406689,
onTrack: onTrack
});
</script>
</body>
</html>When developing and testing your widget integration, debugging errors effectively is crucial for identifying and resolving issues quickly.
Always set silent: false (or omit the silent property, as this is the default) during development. This ensures error messages and icons are displayed, making it easier to identify problems.
SIR('addWidget', '#widget-container', 'match.scoreboard', {
matchId: 12345678,
silent: false // Show errors during development
});Browser developer tools are essential for debugging widget errors:
Open the Console
F12 or Ctrl+Shift+J (Windows/Linux) / Cmd+Option+J (Mac)F12 or Ctrl+Shift+K (Windows/Linux) / Cmd+Option+K (Mac)Look for Error Messages
Inspect Network Requests
Symptoms: Nothing is displayed, no error message, widget container remains empty.
Debugging steps:
Example check:
// Verify SIR function is available
console.log(typeof SIR); // should output "function"Implement comprehensive error logging to help diagnose issues:
const onTrack = (eventType, data) => {
console.log('Widget event:', eventType);
if (eventType === 'data_change') {
if (data.error) {
// Log detailed error information
console.error('Widget error occurred:', {
error: data.error,
widgetData: data,
timestamp: new Date().toISOString()
});
} else {
console.log('Widget loaded successfully');
}
}
if (eventType === 'license_error') {
console.error('License error:', data.error);
}
};Follow these best practices to implement robust error handling:
Use environment-specific settings to balance debugging capabilities with user experience:
const isProduction = window.location.hostname !== 'localhost';
SIR('addWidget', '#widget-container', 'match.scoreboard', {
matchId: 12345678,
silent: isProduction, // Hide errors in production only
onTrack: (eventType, data) => {
if (!isProduction && data.error) {
// Detailed logging in development
console.error('Widget error:', data.error);
}
// Production error tracking (e.g., send to analytics)
if (isProduction && data.error) {
// trackError(data.error);
}
}
});Always consider what users should see when a widget fails to load:
<div id="widget-wrapper">
<div id="widget-container"></div>
<div id="fallback-content" style="display: none;">
<p>Live match data is temporarily unavailable.</p>
<a href="/schedule">View match schedule</a>
</div>
</div>
<script>
const showFallback = () => {
document.getElementById('widget-container').style.display = 'none';
document.getElementById('fallback-content').style.display = 'block';
};
SIR('addWidget', '#widget-container', 'match.scoreboard', {
matchId: 12345678,
silent: true,
onTrack: (eventType, data) => {
if (eventType === 'data_change' && data.error) {
showFallback();
}
}
});
</script>Licensing errors require special attention as they indicate configuration or subscription issues:
SIR('addWidget', '#widget-container', 'match.scoreboard', {
matchId: 12345678,
onTrack: (eventType, data) => {
if (eventType === 'license_error') {
console.error('License error:', data.error);
// Notify your team about license issues
// notifyAdmin('Widget license error', data.error);
// Show user-friendly message
document.getElementById('widget-container').innerHTML =
'<p>This feature is currently unavailable.</p>';
}
}
});Prevent errors by validating configuration before attempting to load widgets:
function loadWidget(matchId) {
// Validate matchId
if (!matchId || typeof matchId !== 'number') {
console.error('Invalid matchId:', matchId);
return;
}
SIR('addWidget', '#widget-container', 'match.scoreboard', {
matchId: matchId,
onTrack: (eventType, data) => {
if (eventType === 'data_change' && data.error) {
console.error('Widget failed to load:', data.error);
}
}
});
}
// Usage
loadWidget(12345678); // Valid
loadWidget('invalid'); // Prevented with error messageRemove or hide widget containers when errors occur to maintain clean page layouts:
SIR('addWidget', '#widget-container', 'match.scoreboard', {
matchId: 12345678,
onTrack: (eventType, data) => {
if (eventType === 'data_change' && data.error) {
const container = document.getElementById('widget-container');
// Option 1: Hide the container
container.style.display = 'none';
// Option 2: Remove it entirely
// container.remove();
// Option 3: Replace with message
// container.innerHTML = '<p>Content unavailable</p>';
}
}
});onTrack callback and all available events