fix frontend error

This commit is contained in:
NA-Wen 2026-03-11 11:22:18 +08:00
parent cf8d7f0f05
commit 54ad9a57ee
4 changed files with 84 additions and 21 deletions

View File

@ -197,7 +197,7 @@ export async function fetchWorkflowsWithDesc() {
const filesWithDesc = await Promise.all(
data.workflows.map(async (filename) => {
try {
const response = await fetch(apiUrl(`/api/workflows/${encodeURIComponent(filename)}/get`))
const response = await fetch(apiUrl(`/api/workflows/${encodeURIComponent(filename)}/desc`))
const fileData = await response.json()
return {
name: filename,

View File

@ -1,8 +1,15 @@
"""Application bootstrap helpers for the FastAPI server."""
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from server import state
from server.config_schema_router import router as config_schema_router
from server.routes import ALL_ROUTERS
from utils.error_handler import add_exception_handlers
from utils.middleware import add_middleware
def init_app(app: FastAPI) -> None:
"""Apply shared middleware, routers, and global state to ``app``."""
@ -15,4 +22,11 @@ def init_app(app: FastAPI) -> None:
)
add_exception_handlers(app)
add_middleware(app)
add_middleware(app)
state.init_state()
for router in ALL_ROUTERS:
app.include_router(router)
app.include_router(config_schema_router)

View File

@ -153,6 +153,69 @@ async def get_workflow_args(filename: str):
)
@router.get("/api/workflows/{filename}/desc")
async def get_workflow_desc(filename: str):
try:
safe_filename = validate_workflow_filename(filename, require_yaml_extension=True)
file_path = YAML_DIR / safe_filename
if not file_path.exists() or not file_path.is_file():
raise ResourceNotFoundError(
"Workflow file not found",
resource_type="workflow",
resource_id=safe_filename,
)
# Load and validate YAML content
raw_content = file_path.read_text(encoding="utf-8")
_, yaml_content = validate_workflow_content(safe_filename, raw_content)
desc = ""
if isinstance(yaml_content, dict):
graph = yaml_content.get("graph") or {}
if isinstance(graph, dict):
desc = graph.get("description") or ""
if len(desc) == 0:
raise ResourceNotFoundError(
"Workflow file does not have args",
resource_type="workflow",
resource_id=safe_filename,
)
logger = get_server_logger()
logger.info(
"Workflow description retrieved",
log_type=LogType.WORKFLOW,
filename=safe_filename,
)
return {"description": desc}
except ValidationError as exc:
# 参数或文件名等校验错误
raise HTTPException(
status_code=400,
detail={"message": str(exc)},
)
except SecurityError as exc:
# 安全相关错误(例如路径遍历)
raise HTTPException(
status_code=400,
detail={"message": str(exc)},
)
except ResourceNotFoundError as exc:
# 文件不存在
raise HTTPException(
status_code=404,
detail={"message": str(exc)},
)
except Exception as exc:
logger = get_server_logger()
logger.log_exception(exc, f"Unexpected error retrieving workflow args: {filename}")
# 兜底错误
raise HTTPException(
status_code=500,
detail={"message": f"Failed to retrieve workflow args: {exc}"},
)
@router.post("/api/workflows/upload/content")
async def upload_workflow_content(request: WorkflowUploadContentRequest):
return _persist_workflow_from_content(
@ -294,4 +357,5 @@ async def get_workflow_raw_content(filename: str):
except Exception as exc:
logger = get_server_logger()
logger.log_exception(exc, f"Unexpected error retrieving workflow: {filename}")
raise WorkflowExecutionError(f"Failed to retrieve workflow: {exc}")
raise WorkflowExecutionError(f"Failed to retrieve workflow: {exc}")

View File

@ -18,31 +18,16 @@ from utils.structured_logger import get_server_logger, LogType
def _update_workflow_id(content: str, workflow_id: str) -> str:
# Pattern to match graph:\n id: <value>
pattern = re.compile(r"(graph:\s*\n\s*id:\s*).*$", re.MULTILINE)
pattern = re.compile(r"^(id:\\s*).*$", re.MULTILINE)
match = pattern.search(content)
if match:
# Replace the value after "graph:\n id: "
return pattern.sub(rf"\1{workflow_id}", content, count=1)
return pattern.sub(rf"\\1{workflow_id}", content, count=1)
# If no graph.id found, look for standalone id: at root level (legacy support)
root_id_pattern = re.compile(r"^(id:\s*).*$", re.MULTILINE)
root_match = root_id_pattern.search(content)
if root_match:
return root_id_pattern.sub(rf"\1{workflow_id}", content, count=1)
# If neither found, add graph.id after graph: section if it exists
graph_pattern = re.compile(r"(graph:\s*\n)")
graph_match = graph_pattern.search(content)
if graph_match:
return graph_pattern.sub(rf"\1 id: {workflow_id}\n", content, count=1)
# Fallback (is invalid)
lines = content.splitlines()
insert_index = 0
if lines and lines[0].strip() == "---":
insert_index = 1
lines.insert(insert_index, f"graph:\n id: {workflow_id}")
lines.insert(insert_index, f"id: {workflow_id}")
updated = "\n".join(lines)
if content.endswith("\n"):
updated += "\n"