Merge pull request #958 from SuanmoSuanyangTechnology/fix/wxy_031
feat(exception): enhance I18nException response format and add error code mapping
This commit is contained in:
@@ -219,6 +219,7 @@ def delete_app(
|
|||||||
|
|
||||||
@router.post("/{app_id}/copy", summary="复制应用")
|
@router.post("/{app_id}/copy", summary="复制应用")
|
||||||
@cur_workspace_access_guard()
|
@cur_workspace_access_guard()
|
||||||
|
@check_app_quota
|
||||||
def copy_app(
|
def copy_app(
|
||||||
app_id: uuid.UUID,
|
app_id: uuid.UUID,
|
||||||
new_name: Optional[str] = None,
|
new_name: Optional[str] = None,
|
||||||
@@ -1144,6 +1145,7 @@ async def import_workflow_config(
|
|||||||
|
|
||||||
@router.post("/workflow/import/save")
|
@router.post("/workflow/import/save")
|
||||||
@cur_workspace_access_guard()
|
@cur_workspace_access_guard()
|
||||||
|
@check_app_quota
|
||||||
async def save_workflow_import(
|
async def save_workflow_import(
|
||||||
data: WorkflowImportSave,
|
data: WorkflowImportSave,
|
||||||
db: Session = Depends(get_db),
|
db: Session = Depends(get_db),
|
||||||
@@ -1281,6 +1283,10 @@ async def import_app(
|
|||||||
return fail(msg="YAML 格式无效,缺少 app 字段", code=BizCode.BAD_REQUEST)
|
return fail(msg="YAML 格式无效,缺少 app 字段", code=BizCode.BAD_REQUEST)
|
||||||
|
|
||||||
target_app_id = uuid.UUID(app_id) if app_id else None
|
target_app_id = uuid.UUID(app_id) if app_id else None
|
||||||
|
# 仅新建应用时检查配额,覆盖已有应用时跳过
|
||||||
|
if target_app_id is None:
|
||||||
|
from app.core.quota_manager import _check_quota
|
||||||
|
_check_quota(db, current_user.tenant_id, "app_quota", "app")
|
||||||
result_app, warnings = AppDslService(db).import_dsl(
|
result_app, warnings = AppDslService(db).import_dsl(
|
||||||
dsl=dsl,
|
dsl=dsl,
|
||||||
workspace_id=current_user.current_workspace_id,
|
workspace_id=current_user.current_workspace_id,
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ class BizCode(IntEnum):
|
|||||||
API_KEY_DAILY_LIMIT_EXCEEDED = 3015
|
API_KEY_DAILY_LIMIT_EXCEEDED = 3015
|
||||||
API_KEY_QUOTA_EXCEEDED = 3016
|
API_KEY_QUOTA_EXCEEDED = 3016
|
||||||
API_KEY_RATE_LIMIT_EXCEEDED = 3017
|
API_KEY_RATE_LIMIT_EXCEEDED = 3017
|
||||||
|
QUOTA_EXCEEDED = 3018
|
||||||
|
RATE_LIMIT_EXCEEDED = 3019
|
||||||
# 资源(4xxx)
|
# 资源(4xxx)
|
||||||
NOT_FOUND = 4000
|
NOT_FOUND = 4000
|
||||||
USER_NOT_FOUND = 4001
|
USER_NOT_FOUND = 4001
|
||||||
@@ -156,7 +158,8 @@ HTTP_MAPPING = {
|
|||||||
BizCode.API_KEY_QPS_LIMIT_EXCEEDED: 429,
|
BizCode.API_KEY_QPS_LIMIT_EXCEEDED: 429,
|
||||||
BizCode.API_KEY_DAILY_LIMIT_EXCEEDED: 429,
|
BizCode.API_KEY_DAILY_LIMIT_EXCEEDED: 429,
|
||||||
BizCode.API_KEY_QUOTA_EXCEEDED: 429,
|
BizCode.API_KEY_QUOTA_EXCEEDED: 429,
|
||||||
|
BizCode.QUOTA_EXCEEDED: 402,
|
||||||
|
|
||||||
BizCode.MODEL_CONFIG_INVALID: 400,
|
BizCode.MODEL_CONFIG_INVALID: 400,
|
||||||
BizCode.API_KEY_MISSING: 400,
|
BizCode.API_KEY_MISSING: 400,
|
||||||
BizCode.PROVIDER_NOT_SUPPORTED: 400,
|
BizCode.PROVIDER_NOT_SUPPORTED: 400,
|
||||||
@@ -185,4 +188,21 @@ HTTP_MAPPING = {
|
|||||||
BizCode.DB_ERROR: 500,
|
BizCode.DB_ERROR: 500,
|
||||||
BizCode.SERVICE_UNAVAILABLE: 503,
|
BizCode.SERVICE_UNAVAILABLE: 503,
|
||||||
BizCode.RATE_LIMITED: 429,
|
BizCode.RATE_LIMITED: 429,
|
||||||
|
BizCode.RATE_LIMIT_EXCEEDED: 429,
|
||||||
|
}
|
||||||
|
|
||||||
|
ERROR_CODE_TO_BIZ_CODE = {
|
||||||
|
"QUOTA_EXCEEDED": BizCode.QUOTA_EXCEEDED,
|
||||||
|
"RATE_LIMIT_EXCEEDED": BizCode.RATE_LIMIT_EXCEEDED,
|
||||||
|
"API_KEY_NOT_FOUND": BizCode.API_KEY_NOT_FOUND,
|
||||||
|
"API_KEY_INVALID": BizCode.API_KEY_INVALID,
|
||||||
|
"API_KEY_EXPIRED": BizCode.API_KEY_EXPIRED,
|
||||||
|
"WORKSPACE_NOT_FOUND": BizCode.WORKSPACE_NOT_FOUND,
|
||||||
|
"WORKSPACE_NO_ACCESS": BizCode.WORKSPACE_NO_ACCESS,
|
||||||
|
"PERMISSION_DENIED": BizCode.PERMISSION_DENIED,
|
||||||
|
"TOKEN_EXPIRED": BizCode.TOKEN_EXPIRED,
|
||||||
|
"TOKEN_INVALID": BizCode.TOKEN_INVALID,
|
||||||
|
"VALIDATION_FAILED": BizCode.VALIDATION_FAILED,
|
||||||
|
"INVALID_PARAMETER": BizCode.INVALID_PARAMETER,
|
||||||
|
"MISSING_PARAMETER": BizCode.MISSING_PARAMETER,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,12 +6,14 @@ error messages based on the current request's language.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import time
|
||||||
from contextvars import ContextVar
|
from contextvars import ContextVar
|
||||||
from typing import Any, Dict, Optional
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from fastapi import HTTPException, Request
|
from fastapi import HTTPException, Request
|
||||||
|
|
||||||
from app.i18n.service import get_translation_service
|
from app.i18n.service import get_translation_service
|
||||||
|
from app.core.error_codes import ERROR_CODE_TO_BIZ_CODE, BizCode
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -118,15 +120,24 @@ class I18nException(HTTPException):
|
|||||||
**params
|
**params
|
||||||
)
|
)
|
||||||
|
|
||||||
# Build error detail
|
# Convert error_code string to BizCode value
|
||||||
detail = {
|
biz_code = ERROR_CODE_TO_BIZ_CODE.get(
|
||||||
"error_code": self.error_code,
|
self.error_code,
|
||||||
"message": message,
|
BizCode.BAD_REQUEST
|
||||||
}
|
)
|
||||||
|
|
||||||
# Add parameters to detail if provided
|
# Build error detail in standard format for compatibility
|
||||||
if params:
|
# main.py handler expects "message" and "error_code" fields for filtering
|
||||||
detail["params"] = params
|
# but we also include standard format fields
|
||||||
|
detail = {
|
||||||
|
"code": biz_code.value,
|
||||||
|
"msg": message,
|
||||||
|
"message": message,
|
||||||
|
"error_code": self.error_code,
|
||||||
|
"data": params if params else {},
|
||||||
|
"error": message,
|
||||||
|
"time": int(time.time() * 1000),
|
||||||
|
}
|
||||||
|
|
||||||
# Initialize HTTPException
|
# Initialize HTTPException
|
||||||
super().__init__(
|
super().__init__(
|
||||||
|
|||||||
Reference in New Issue
Block a user