You've already forked DataMate
* refactor: 修改调整数据归集实现,删除无用代码,优化代码结构 * feature: 每天凌晨00:00扫描所有数据集,检查数据集是否超过了预设的保留天数,超出保留天数的数据集调用删除接口进行删除 * fix: 修改删除数据集文件的逻辑,上传到数据集中的文件会同时删除数据库中的记录和文件系统中的文件,归集过来的文件仅删除数据库中的记录 * fix: 增加参数校验和接口定义,删除不使用的接口 * fix: 数据集统计数据默认为0 * feature: 数据集状态增加流转,创建时为草稿状态,上传文件或者归集文件后修改为活动状态 * refactor: 修改分页查询归集任务的代码 * fix: 更新后重新执行;归集任务执行增加事务控制 * feature: 创建归集任务时能够同步创建数据集,更新归集任务时能更新到指定数据集 * fix: 创建归集任务不需要创建数据集时不应该报错 * fix: 修复删除文件时数据集的统计数据不变动 * feature: 查询数据集详情时能够获取到文件标签分布 * fix: tags为空时不进行分析 * fix: 状态修改为ACTIVE * fix: 修改解析tag的方法 * feature: 实现创建、分页查询、删除配比任务 * feature: 实现创建、分页查询、删除配比任务的前端交互 * fix: 修复进度计算异常导致的页面报错
102 lines
3.3 KiB
Python
102 lines
3.3 KiB
Python
"""
|
|
全局自定义异常类定义
|
|
"""
|
|
from fastapi.responses import JSONResponse
|
|
from fastapi.exceptions import RequestValidationError
|
|
from starlette.exceptions import HTTPException as StarletteHTTPException
|
|
from fastapi import FastAPI, Request, HTTPException, status
|
|
|
|
from .core.logging import setup_logging, get_logger
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
# 自定义异常处理器:StarletteHTTPException (包括404等)
|
|
async def starlette_http_exception_handler(request: Request, exc: StarletteHTTPException):
|
|
"""将Starlette的HTTPException转换为标准响应格式"""
|
|
return JSONResponse(
|
|
status_code=exc.status_code,
|
|
content={
|
|
"code": exc.status_code,
|
|
"message": "error",
|
|
"data": {
|
|
"detail": exc.detail
|
|
}
|
|
}
|
|
)
|
|
|
|
# 自定义异常处理器:FastAPI HTTPException
|
|
async def fastapi_http_exception_handler(request: Request, exc: HTTPException):
|
|
"""将FastAPI的HTTPException转换为标准响应格式"""
|
|
return JSONResponse(
|
|
status_code=exc.status_code,
|
|
content={
|
|
"code": exc.status_code,
|
|
"message": "error",
|
|
"data": {
|
|
"detail": exc.detail
|
|
}
|
|
}
|
|
)
|
|
|
|
# 自定义异常处理器:RequestValidationError
|
|
async def validation_exception_handler(request: Request, exc: RequestValidationError):
|
|
"""将请求验证错误转换为标准响应格式"""
|
|
# 仅返回每个错误的简要 detail 文本(来自 Pydantic 错误的 `msg` 字段),不返回整个错误对象
|
|
raw_errors = exc.errors() or []
|
|
errors = [err.get("msg", "Validation error") for err in raw_errors]
|
|
|
|
return JSONResponse(
|
|
status_code=422,
|
|
content={
|
|
"code": 422,
|
|
"message": "error",
|
|
"data": {
|
|
"detail": "Validation error",
|
|
"errors": errors,
|
|
},
|
|
},
|
|
)
|
|
|
|
# 自定义异常处理器:未捕获的异常
|
|
async def general_exception_handler(request: Request, exc: Exception):
|
|
"""将未捕获的异常转换为标准响应格式"""
|
|
logger.error(f"Unhandled exception: {exc}", exc_info=True)
|
|
return JSONResponse(
|
|
status_code=500,
|
|
content={
|
|
"code": 500,
|
|
"message": "error",
|
|
"data": {
|
|
"detail": "Internal server error"
|
|
}
|
|
}
|
|
)
|
|
|
|
class LabelStudioAdapterException(Exception):
|
|
"""Label Studio Adapter 基础异常类"""
|
|
pass
|
|
|
|
class DatasetMappingNotFoundError(LabelStudioAdapterException):
|
|
"""数据集映射未找到异常"""
|
|
def __init__(self, mapping_id: str):
|
|
self.mapping_id = mapping_id
|
|
super().__init__(f"Dataset mapping not found: {mapping_id}")
|
|
|
|
class NoDatasetInfoFoundError(LabelStudioAdapterException):
|
|
"""无法获取数据集信息异常"""
|
|
def __init__(self, dataset_uuid: str):
|
|
self.dataset_uuid = dataset_uuid
|
|
super().__init__(f"Failed to get dataset info: {dataset_uuid}")
|
|
|
|
class LabelStudioClientError(LabelStudioAdapterException):
|
|
"""Label Studio 客户端错误"""
|
|
pass
|
|
|
|
class DMServiceClientError(LabelStudioAdapterException):
|
|
"""DM 服务客户端错误"""
|
|
pass
|
|
|
|
class SyncServiceError(LabelStudioAdapterException):
|
|
"""同步服务错误"""
|
|
pass
|