Make startup crash-proof against corrupt/empty state
Browse files- database.py: catch JSONDecodeError when loading snapshot from DB
- server.py: wrap load_simulation() in try/except — any error starts fresh
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
src/soci/api/server.py
CHANGED
|
@@ -275,8 +275,13 @@ async def lifespan(app: FastAPI):
|
|
| 275 |
data_dir = Path(os.environ.get("SOCI_DATA_DIR", "data"))
|
| 276 |
await load_state_from_github(data_dir)
|
| 277 |
|
| 278 |
-
# Try to resume
|
| 279 |
-
sim =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 280 |
if sim is None:
|
| 281 |
# Create new
|
| 282 |
config_dir = Path(__file__).parents[3] / "config"
|
|
|
|
| 275 |
data_dir = Path(os.environ.get("SOCI_DATA_DIR", "data"))
|
| 276 |
await load_state_from_github(data_dir)
|
| 277 |
|
| 278 |
+
# Try to resume — any failure falls back to a fresh simulation
|
| 279 |
+
sim = None
|
| 280 |
+
try:
|
| 281 |
+
sim = await load_simulation(db, llm)
|
| 282 |
+
except Exception as e:
|
| 283 |
+
logger.warning(f"Failed to load saved simulation, starting fresh: {e}")
|
| 284 |
+
|
| 285 |
if sim is None:
|
| 286 |
# Create new
|
| 287 |
config_dir = Path(__file__).parents[3] / "config"
|
src/soci/persistence/database.py
CHANGED
|
@@ -98,7 +98,10 @@ class Database:
|
|
| 98 |
)
|
| 99 |
row = await cursor.fetchone()
|
| 100 |
if row:
|
| 101 |
-
|
|
|
|
|
|
|
|
|
|
| 102 |
return None
|
| 103 |
|
| 104 |
async def list_snapshots(self) -> list[dict]:
|
|
|
|
| 98 |
)
|
| 99 |
row = await cursor.fetchone()
|
| 100 |
if row:
|
| 101 |
+
try:
|
| 102 |
+
return json.loads(row[0])
|
| 103 |
+
except (json.JSONDecodeError, ValueError) as e:
|
| 104 |
+
logger.warning(f"Corrupt snapshot in DB, ignoring: {e}")
|
| 105 |
return None
|
| 106 |
|
| 107 |
async def list_snapshots(self) -> list[dict]:
|