Error Handling
Learn how to handle errors gracefully in your Predicate automation scripts. Build resilient automation that recovers from failures and provides meaningful error messages.
Common Error Scenarios
Web automation is inherently unreliable. Networks fail, pages change, elements disappear. Proper error handling makes your automation production-ready.
Elements Not Found
The most common error: an element you're looking for doesn't exist.
from predicate import snapshot, find, click
snap = snapshot(browser)
button = find(snap,Timeout Errors
Operations that take too long should timeout gracefully:
from predicate import wait_for
# Wait with timeout
result = wait_for(browser, "role=heading text~'Success'", timeout=10.0)
if result.found:
print("Success message appeared!")
else:Network Errors
Handle network failures during page loads or API calls:
from predicate import PredicateBrowser, snapshot
import time
with PredicateBrowser(api_key="sk_...") as browser:
max_retries = 3
retry_count = 0
while retry_count < max_retries:Error Handling Patterns
Retry with Exponential Backoff
import time
def retry_with_backoff(func, max_retries=3, base_delay=1):
"""Retry a function with exponential backoff"""
for attempt in range(max_retries):
try:Fallback Strategies
from predicate import snapshot, find, click
snap = snapshot(browser)
# Try primary button first
submit_btn = find(snap, "role=button text~'Submit Form'")
if not submit_btn:
# Fallback: try alternative textGraceful Degradation
from predicate import snapshot, find, click, wait_for
def login(browser, email, password):
"""Login with error handling and graceful degradation"""
try:
# Navigate to login page
browser.page.Logging and Debugging
Structured Logging
import logging
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# Use in automation
defScreenshots for Debugging
# Take screenshot on error
try:
result = wait_for(browser, "role=button text~'submit'", timeout=5.0)
if not result.found:
browser.page.screenshot(path="element_not_found.png")
raise ValueError("Submit button not found")
except Exception as e:
browser.page.screenshot(path="error_state.png")
raiseBest Practices
1. Always Validate Element Existence
# Good
button = find(snap, "role=button text~'submit'")
if button:
click(browser, button.id)
else:
# Handle missing element
# Avoid
button = find(snap, "role=button text~'submit'")
click(browser, button.id) # Might crash if button is None2. Use Appropriate Timeouts
# Short timeout for fast operations
result = wait_for(browser, "role=alert", timeout=2.0)
# Long timeout for slow operations
result = wait_for(browser, "text~'Report generated'", timeout=120.0)3. Provide Meaningful Error Messages
# Good
if not button:
raise ValueError(f"Submit button not found with query: {query}. Page might have changed.")
# Avoid
if not button:
raise ValueError("Error")4. Clean Up Resources
from predicate import PredicateBrowser
# Use context manager for automatic cleanup
with PredicateBrowser(api_key="sk_...") as browser:
# Automation code
pass # Browser closes automatically
# Or manual cleanup
browser = PredicateBrowser(api_key="sk_...")
try:
# Automation code
finally:
browser.close() # Always closeCommon Error Types
ValueError
Element not found or invalid query:
try:
button = find(snap, "role=button text~'submit'")
if not button:
raise ValueError("Submit button not found")
except ValueError as e:
print(f"Validation error: {e}")TimeoutError
Operation took too long:
try:
result = wait_for(browser, "text~'Success'", timeout=10.0)
if not result.found:
raise TimeoutError("Success message didn't appear")
except TimeoutError as e:
print(f"Timeout: {e}")NetworkError
Network or navigation failures:
try:
browser.page.goto("https://example.com", timeout=30000)
except Exception as e:
print(f"Network error: {e}")
# Retry or fail gracefullyNext Steps
- Examples → - See error handling in real-world scenarios
- Best Practices → - Advanced error handling patterns
- SDK Reference → - Complete SDK documentation