mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
fix: 处理客户端断开连接情况,以防止出现虚假的系统错误报告
捕获 starlette.requests.ClientDisconnect 异常,避免客户端主动断开连接时被当作系统未知错误(500)处理。 - 在读取请求体阶段捕获 ClientDisconnect,返回 499 状态码 - 在 adapter.handle 阶段捕获 ClientDisconnect,记录审计日志并返回 499 - 日志级别从 ERROR 降为 WARNING,减少误报告警噪音
This commit is contained in:
@@ -5,8 +5,10 @@ from enum import Enum
|
|||||||
from typing import TYPE_CHECKING, Any
|
from typing import TYPE_CHECKING, Any
|
||||||
|
|
||||||
from fastapi import HTTPException, Request
|
from fastapi import HTTPException, Request
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
from starlette.requests import ClientDisconnect
|
||||||
|
|
||||||
from src.config.settings import config
|
from src.config.settings import config
|
||||||
from src.core.enums import UserRole
|
from src.core.enums import UserRole
|
||||||
@@ -144,6 +146,16 @@ class ApiRequestPipeline:
|
|||||||
status_code=408,
|
status_code=408,
|
||||||
detail=f"Request timeout: body not received within {timeout_sec} seconds",
|
detail=f"Request timeout: body not received within {timeout_sec} seconds",
|
||||||
)
|
)
|
||||||
|
except ClientDisconnect:
|
||||||
|
logger.warning(
|
||||||
|
"[Pipeline] 客户端在读取请求体期间断开连接: {} {}",
|
||||||
|
http_request.method,
|
||||||
|
http_request.url.path,
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=499,
|
||||||
|
content={"error": "client_disconnected", "message": "Client closed request"},
|
||||||
|
)
|
||||||
context_start = PerfRecorder.start(force=perf_sampled)
|
context_start = PerfRecorder.start(force=perf_sampled)
|
||||||
context = ApiRequestContext.build(
|
context = ApiRequestContext.build(
|
||||||
request=http_request,
|
request=http_request,
|
||||||
@@ -199,6 +211,25 @@ class ApiRequestPipeline:
|
|||||||
error=err_detail,
|
error=err_detail,
|
||||||
)
|
)
|
||||||
raise
|
raise
|
||||||
|
except ClientDisconnect:
|
||||||
|
handle_duration = PerfRecorder.stop(handle_start, "pipeline_handle", labels=perf_labels)
|
||||||
|
_record_perf_metric("handle_ms", handle_duration)
|
||||||
|
logger.warning(
|
||||||
|
"[Pipeline] 客户端在处理期间断开连接: {} {}",
|
||||||
|
context.request.method,
|
||||||
|
context.request.url.path,
|
||||||
|
)
|
||||||
|
self._record_audit_event(
|
||||||
|
context,
|
||||||
|
adapter,
|
||||||
|
success=False,
|
||||||
|
status_code=499,
|
||||||
|
error="client_disconnected",
|
||||||
|
)
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=499,
|
||||||
|
content={"error": "client_disconnected", "message": "Client closed request"},
|
||||||
|
)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
handle_duration = PerfRecorder.stop(handle_start, "pipeline_handle", labels=perf_labels)
|
handle_duration = PerfRecorder.stop(handle_start, "pipeline_handle", labels=perf_labels)
|
||||||
_record_perf_metric("handle_ms", handle_duration)
|
_record_perf_metric("handle_ms", handle_duration)
|
||||||
|
|||||||
Reference in New Issue
Block a user