Learn how to handle errors gracefully in your Predicate automation scripts. Build resilient automation that recovers from failures and provides meaningful error messages.
Web automation is inherently unreliable. Networks fail, pages change, elements disappear. Proper error handling makes your automation production-ready.
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,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: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: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: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 textfrom 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.import logging
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# Use in automation
def# 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")
raise# 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 None# 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)# 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")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 closeElement 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}")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}")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 gracefully