|
9 | 9 |
|
10 | 10 | from flask import Flask, make_response, redirect, request, send_file |
11 | 11 | from flask_restful import Api, Resource |
| 12 | +from selenium.common import exceptions as selenium_exceptions |
12 | 13 |
|
13 | 14 | from automator import KindleAutomator |
14 | 15 | from handlers.test_fixtures_handler import TestFixturesHandler |
@@ -123,21 +124,48 @@ def post(self): |
123 | 124 | return {"error": str(e)}, 500 |
124 | 125 |
|
125 | 126 |
|
| 127 | +def handle_uiautomator_crash(f): |
| 128 | + """Decorator to handle UiAutomator2 server crashes by restarting the driver.""" |
| 129 | + |
| 130 | + def wrapper(*args, **kwargs): |
| 131 | + try: |
| 132 | + return f(*args, **kwargs) |
| 133 | + except Exception as e: |
| 134 | + # Check if it's the UiAutomator2 server crash error |
| 135 | + if isinstance(e, selenium_exceptions.WebDriverException) and "cannot be proxied to UiAutomator2 server because the instrumentation process is not running" in str(e): |
| 136 | + logger.warning("UiAutomator2 server crashed. Attempting to restart driver...") |
| 137 | + if server.automator and server.automator.ensure_driver_running(): |
| 138 | + # Retry the operation after driver restart |
| 139 | + logger.info("Driver restarted successfully. Retrying operation...") |
| 140 | + return f(*args, **kwargs) |
| 141 | + else: |
| 142 | + logger.error("Failed to restart driver after UiAutomator2 server crash") |
| 143 | + return {"error": "Failed to restart driver after UiAutomator2 server crash"}, 500 |
| 144 | + # Re-raise other exceptions |
| 145 | + raise |
| 146 | + |
| 147 | + return wrapper |
| 148 | + |
| 149 | + |
126 | 150 | def ensure_automator_healthy(f): |
127 | 151 | """Decorator to ensure automator is initialized and healthy before each operation.""" |
128 | 152 |
|
129 | | - def wrapper(*args, **kwargs): |
130 | | - try: |
131 | | - if not server.automator: |
132 | | - logger.info("No automator found, initializing...") |
133 | | - server.initialize_automator() |
134 | | - if not server.automator.initialize_driver(): |
135 | | - return {"error": "Failed to initialize driver"}, 500 |
| 153 | + @handle_uiautomator_crash |
| 154 | + def wrapped_function(*args, **kwargs): |
| 155 | + if not server.automator: |
| 156 | + logger.info("No automator found, initializing...") |
| 157 | + server.initialize_automator() |
| 158 | + if not server.automator.initialize_driver(): |
| 159 | + return {"error": "Failed to initialize driver"}, 500 |
136 | 160 |
|
137 | | - if not server.automator.ensure_driver_running(): |
138 | | - return {"error": "Failed to ensure driver is running"}, 500 |
| 161 | + if not server.automator.ensure_driver_running(): |
| 162 | + return {"error": "Failed to ensure driver is running"}, 500 |
139 | 163 |
|
140 | | - return f(*args, **kwargs) |
| 164 | + return f(*args, **kwargs) |
| 165 | + |
| 166 | + def wrapper(*args, **kwargs): |
| 167 | + try: |
| 168 | + return wrapped_function(*args, **kwargs) |
141 | 169 | except Exception as e: |
142 | 170 | logger.error(f"Error in automator health check: {e}") |
143 | 171 | logger.error(f"Traceback: {traceback.format_exc()}") |
|
0 commit comments