mirror of
https://github.com/MervinPraison/PraisonAIUI.git
synced 2026-11-07 05:56:17 -10:00
* fix: surface platform-board integration errors instead of empty state (fixes #74) Distinguish connection, auth, and HTTP failures from zero issues. Add __main__ uvicorn bootstrap with HOST/PORT env overrides. Co-authored-by: Cursor <[email protected]> * fix: improve platform-board error handling - Add explicit 200 status code check to prevent 3xx/204 from proceeding to JSON parsing - Add safe JSON parsing with try/catch to handle invalid JSON responses - Add defensive type checking for non-dict/non-list JSON responses Addresses reviewer feedback from Gemini Code Assist review. Co-authored-by: Mervin Praison <[email protected]> --------- Co-authored-by: MervinPraison <[email protected]> Co-authored-by: Cursor <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Mervin Praison <[email protected]>
This commit is contained in:
1 file changed
+63
-17
@@ -14,30 +14,76 @@ aiui.set_pages(["issues-board"])
|
||||
aiui.set_dashboard(sidebar=True)
|
||||
|
||||
|
||||
@aiui.page("issues-board", title="Issues", icon="📌", group="Work")
|
||||
async def issues_board():
|
||||
issues = []
|
||||
async def _fetch_issues() -> tuple[list, str | None]:
|
||||
"""Return (issues, error_message). error_message is None on success."""
|
||||
url = f"{PLATFORM.rstrip('/')}/api/v1/workspaces/{WORKSPACE_ID}/issues"
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=10.0) as c:
|
||||
r = await c.get(url)
|
||||
if r.status_code == 200:
|
||||
d = r.json()
|
||||
issues = d if isinstance(d, list) else d.get("issues") or d.get("items") or []
|
||||
except Exception:
|
||||
pass
|
||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
||||
response = await client.get(url)
|
||||
except httpx.ConnectError:
|
||||
return [], f"Cannot reach platform at {PLATFORM}"
|
||||
except httpx.TimeoutException:
|
||||
return [], f"Platform request timed out ({PLATFORM})"
|
||||
except Exception as exc:
|
||||
return [], f"Platform request failed: {exc}"
|
||||
|
||||
if response.status_code in (401, 403):
|
||||
return [], f"Platform auth failed (HTTP {response.status_code})"
|
||||
if response.status_code != 200:
|
||||
return [], f"Platform error (HTTP {response.status_code})"
|
||||
|
||||
try:
|
||||
data = response.json()
|
||||
except ValueError:
|
||||
return [], "Platform returned invalid JSON"
|
||||
|
||||
if isinstance(data, list):
|
||||
issues = data
|
||||
elif isinstance(data, dict):
|
||||
issues = data.get("issues") or data.get("items") or []
|
||||
else:
|
||||
issues = []
|
||||
return issues, None
|
||||
|
||||
|
||||
@aiui.page("issues-board", title="Issues", icon="📌", group="Work")
|
||||
async def issues_board():
|
||||
issues, error = await _fetch_issues()
|
||||
|
||||
if error:
|
||||
return aiui.layout([
|
||||
aiui.text(f"Platform: {PLATFORM} · workspace: {WORKSPACE_ID}"),
|
||||
aiui.card("Platform unavailable", footer=error),
|
||||
])
|
||||
|
||||
by: dict[str, list] = {}
|
||||
for i in issues:
|
||||
s = (i.get("status") or "backlog").lower().replace(" ", "_")
|
||||
by.setdefault(s, []).append(i)
|
||||
for issue in issues:
|
||||
status = (issue.get("status") or "backlog").lower().replace(" ", "_")
|
||||
by.setdefault(status, []).append(issue)
|
||||
|
||||
columns = []
|
||||
for sid in ("backlog", "in_progress", "done"):
|
||||
cards = [aiui.card(i.get("title", "Issue"), footer=sid) for i in by.get(sid, [])]
|
||||
columns.append({"id": sid, "title": sid.replace("_", " ").title(), "cards": cards or [aiui.card("(empty)")]})
|
||||
for status_id in ("backlog", "in_progress", "done"):
|
||||
cards = [aiui.card(i.get("title", "Issue"), footer=status_id) for i in by.get(status_id, [])]
|
||||
if not cards:
|
||||
cards = [aiui.card("(no issues)")]
|
||||
columns.append({
|
||||
"id": status_id,
|
||||
"title": status_id.replace("_", " ").title(),
|
||||
"cards": cards,
|
||||
})
|
||||
|
||||
summary = f"{len(issues)} issue(s)" if issues else "No issues in workspace"
|
||||
return aiui.layout([
|
||||
aiui.text(f"Platform: {PLATFORM} · workspace: {WORKSPACE_ID}"),
|
||||
aiui.text(f"Platform: {PLATFORM} · workspace: {WORKSPACE_ID} · {summary}"),
|
||||
aiui.board(columns=columns),
|
||||
])
|
||||
|
||||
|
||||
app = create_app()
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
|
||||
host = os.getenv("HOST", "127.0.0.1")
|
||||
port = int(os.getenv("PORT", "8082"))
|
||||
uvicorn.run(app, host=host, port=port)
|
||||
Reference in new issue
Block a user