mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 00:41:59 +00:00
d8034ca71a
以前有两个「对外地址」:环境变量 AGENTLAB_PUBLIC_URL 只管 OIDC 回调和 Origin 核对,设置里 notify.public_base_url 只管 通知里的链接。只配了环境变量的部署,通知里不带链接;只在设置里填了的,回调又按请求的 Host 拼——违背「一种说法」。 - 新增 core/public_url.py:环境变量优先,其次设置(沿用 notify.public_base_url 这个键),都没有是 None。设置的值缓存在 进程里(中间件按请求核对来源,不能每次查库):启动时 refresh 一次,PUT /api/settings 写完库就 remember,不用重启; 通知、定时任务 Webhook 手里本来就有会话,用 refresh 取,顺手按库里的值对齐缓存 - 地址的形状检查和规范化只有一份(url_problem / normalize),设置接口的中文报错和环境变量的启动校验都用它;环境变量 写错了(没有 http:// 或 https://、带 ? 或 #)启动时就报错,不再拼出坏的回调地址 - GET /api/settings 另给只读的 public_url 一组 {value, env_locked},设置页据此显示「由环境变量指定」;环境变量设了时 PUT 把这一项改成别的值回 409(public_url_env_locked,field 指到这一项),原样写回不算改;public_url 一组写不进库 - notify/service 取地址的那一处、scheduler/webhook 链接里的地址、api/auth 的 OIDC 回调、auth/middleware 的 Origin 核对 都改走 public_base_url;deploy/agentlab.env 把这个变量的说法改成全站唯一的对外访问地址 测试 tests/test_public_url.py:先后顺序(环境变量 > 设置 > 无)、规范化、启动校验、PUT 刷新缓存、环境变量锁定(409、 不挡原样写回)、只配环境变量时通知带链接、OIDC 回调和 Origin 核对认设置里的地址。去掉修复回跑,只配环境变量的通知 链接、按设置核对 Origin 两条都会失败。设置页把它挪到「通用」在后面的前端提交里。
51 lines
2.6 KiB
Python
51 lines
2.6 KiB
Python
"""带机器码的 HTTP 错误。
|
||
|
||
detail 仍是给人看的那一句,老前端照旧直接显示;code 是给程序认的稳定标识。
|
||
以前前端只能按 detail 的开头几个字认出某一类错误,文案一改就悄悄失灵。
|
||
"""
|
||
from __future__ import annotations
|
||
|
||
from fastapi import HTTPException, Request
|
||
from fastapi.responses import JSONResponse
|
||
|
||
#: 限定的数据源一个都不在了(删了或停用了),见 copilot._sources
|
||
DATASOURCE_SCOPE_EMPTY = "datasource_scope_empty"
|
||
|
||
#: 保存数据源时剖析设置不合规(422):field 是出错的那一项(table_max_queries……),说不清是哪一项时没有 field
|
||
PROFILE_SETTINGS_INVALID = "profile_settings_invalid"
|
||
#: 剖析任务开始不了(409,api/catalog.create_profile_job):未开启、数据源停用、没有表结构、快照被改动、这个源已有排队或
|
||
#: 进行中的剖析任务(导入目录、同步起草遇到剖析任务也是它)、按范围挑出 0 张表
|
||
PROFILE_DISABLED = "profile_disabled"
|
||
DATASOURCE_INACTIVE = "datasource_inactive"
|
||
SCHEMA_MISSING = "schema_missing"
|
||
PROFILE_BUSY = "profile_busy"
|
||
SNAPSHOT_TAMPERED = "snapshot_tampered"
|
||
PROFILE_NOTHING = "profile_nothing"
|
||
#: 要停止的剖析任务已经结束了(409)
|
||
CATALOG_PROFILE_FINISHED = "catalog_profile_finished"
|
||
#: 数据目录的后台起草任务(api/catalog.py 的 /catalog/draft-jobs):同一个源已有排队或进行中的任务(409,界面改去
|
||
#: GET /draft-jobs/active 显示那一个)、起草模型用不了(409,不建任务)、要停止的任务已经结束了(409)
|
||
CATALOG_DRAFT_BUSY = "catalog_draft_busy"
|
||
CATALOG_DRAFT_MODEL_UNAVAILABLE = "catalog_draft_model_unavailable"
|
||
CATALOG_DRAFT_FINISHED = "catalog_draft_finished"
|
||
|
||
#: 设置(api/settings.py):对外访问地址由环境变量 AGENTLAB_PUBLIC_URL 指定时,设置里那一项不能改成别的值(409)
|
||
PUBLIC_URL_ENV_LOCKED = "public_url_env_locked"
|
||
|
||
|
||
class CodedHTTPException(HTTPException):
|
||
"""field:出错的是哪一项(表单据此把报错落到那一格)。可选,没有就不出现在返回里。"""
|
||
|
||
def __init__(self, status_code: int, detail: str, code: str, *, field: str | None = None) -> None:
|
||
super().__init__(status_code, detail)
|
||
self.code = code
|
||
self.field = field
|
||
|
||
|
||
async def coded_handler(_: Request, exc: Exception) -> JSONResponse:
|
||
assert isinstance(exc, CodedHTTPException)
|
||
content: dict[str, str] = {"detail": exc.detail, "code": exc.code}
|
||
if exc.field:
|
||
content["field"] = exc.field
|
||
return JSONResponse(status_code=exc.status_code, content=content, headers=exc.headers)
|