""" 施工方案审查API错误码统一定义 集中管理所有接口的错误码和错误响应格式 """ from typing import Dict, Any from fastapi import HTTPException from foundation.logger.loggering import server_logger as logger class ErrorCodes: """错误码常量定义""" # 文件上传接口错误码 (WJSC001-WJSC008) WJSC001 = { "code": "WJSC001", "error_type": "FILE_MISSING", "message": "未上传文件", "status_code": 400 } WJSC002 = { "code": "WJSC002", "error_type": "FILE_MULTIPLE", "message": "仅支持单文件上传", "status_code": 400 } WJSC003 = { "code": "WJSC003", "error_type": "FILE_REJECTED", "message": "格式错误、内容违规、文件为空", "status_code": 400 } WJSC004 = { "code": "WJSC004", "error_type": "FILE_FORMAT_UNSUPPORTED", "message": "文件格式不支持(仅允许pdf/doc/docx)", "status_code": 400 } WJSC005 = { "code": "WJSC005", "error_type": "FILE_SIZE_EXCEEDED", "message": "文件过大(最大不超过50MB)", "status_code": 400 } WJSC007 = { "code": "WJSC007", "error_type": "UNAUTHORIZED", "message": "认证失败(未提供或无效的Authorization)", "status_code": 401 } WJSC008 = { "code": "WJSC008", "error_type": "INVALID_USER", "message": "用户标识未提供或无效", "status_code": 403 } WJSC009 = { "code": "WJSC009", "error_type": "INVALID_PARAMETERS", "message": "请求参数无效或不支持", "status_code": 400 } WJSC011 = { "code": "WJSC011", "error_type": "INTERNAL_ERROR", "message": "服务端内部错误", "status_code": 500 } # 启动审查接口错误码 (QDSC001-QDSC006) QDSC001 = { "code": "QDSC001", "error_type": "MISSING_PARAMETERS", "message": "请求参数缺失", "status_code": 400 } QDSC002 = { "code": "QDSC002", "error_type": "INVALID_PARAM_FORMAT", "message": "请求参数格式错误", "status_code": 400 } QDSC003 = { "code": "QDSC003", "error_type": "UNAUTHORIZED", "message": "认证失败(未提供或无效的Authorization)", "status_code": 401 } QDSC004 = { "code": "QDSC004", "error_type": "INVALID_USER", "message": "用户标识未提供或无效", "status_code": 403 } QDSC005 = { "code": "QDSC005", "error_type": "TASK_NOT_FOUND", "message": "任务ID不存在或已过期", "status_code": 404 } QDSC006 = { "code": "QDSC006", "error_type": "TASK_ALREADY_EXISTS", "message": "任务已存在,请勿重复提交", "status_code": 409 } QDSC007 = { "code": "QDSC007", "error_type": "PROJECT_PLAN_TYPE_INVALID", "message": "无效工程方案类型(未提供或未注册)", "status_code": 400 } QDSC008 = { "code": "QDSC008", "error_type": "ENUM_TYPE_INVALID", "message": "审查枚举类型无效", "status_code": 400 } QDSC009 = { "code": "QDSC009", "error_type": "ENUM_TYPE_CANNOT_BE_NULL", "message": "审查枚举类型不能为空", "status_code": 400 } QDSC010 = { "code": "QDSC010", "error_type": "FILE_INFO_NOT_FOUND", "message": "文件信息获取失败", "status_code": 500 } QDSC011 = { "code": "QDSC011", "error_type": "SERVER_INTERNAL_ERROR", "message": "服务端内部错误", "status_code": 500 } QDSC012 = { "code": "QDSC012", "error_type": "TASK_NOT_FOUND_OR_EXPIRED", "message": "任务ID不存在或已过期,请重新检查callback_task_id是否正确,或重新上传文件", "status_code": 404 } QDSC013 = { "code": "QDSC013", "error_type": "FILE_INFO_NOT_FOUND", "message": "文件信息获取失败,任务ID不存在或已过期", "status_code": 404 } # 审查结果接口错误码 (SCJG001-SCJG008) SCJG001 = { "code": "SCJG001", "error_type": "INVALID_TYPE", "message": "结果类型无效(非'summary'或'issues')", "status_code": 400 } SCJG002 = { "code": "SCJG002", "error_type": "MISSING_PARAM_ID", "message": "callback_task_id缺失", "status_code": 400 } SCJG003 = { "code": "SCJG003", "error_type": "INVALID_ID_FORMAT", "message": "callback_task_id格式错误", "status_code": 400 } SCJG004 = { "code": "SCJG004", "error_type": "UNAUTHORIZED", "message": "认证失败(未提供或无效的Authorization)", "status_code": 401 } SCJG005 = { "code": "SCJG005", "error_type": "INVALID_USER", "message": "用户标识未提供或无效", "status_code": 403 } SCJG006 = { "code": "SCJG006", "error_type": "TASK_NOT_FOUND", "message": "callback_task_id不存在或已过期", "status_code": 404 } SCJG007 = { "code": "SCJG007", "error_type": "NO_REVIEW_RESULTS", "message": "无审查结果数据", "status_code": 404 } SCJG008 = { "code": "SCJG008", "error_type": "SERVER_ERROR", "message": "服务端内部错误(审查结果生成失败)", "status_code": 500 } def create_http_exception(error_code: Dict[str, Any], custom_message: str = None) -> HTTPException: """ 创建HTTP异常 Args: error_code: 错误码字典 custom_message: 自定义错误消息,可选 Returns: HTTPException: FastAPI异常对象 """ detail = { "code": error_code["code"], "error_type": error_code["error_type"], "message": custom_message or error_code["message"] } return HTTPException( status_code=error_code["status_code"], detail=detail ) def create_server_error(error_code: str, original_error: Exception) -> HTTPException: """ 创建服务器内部错误异常 Args: error_code: 错误码 (如 "WJSC008", "QDSC006", "SCJG008") original_error: 原始异常 Returns: HTTPException: FastAPI异常对象 """ error_map = { "WJSC011": ErrorCodes.WJSC011, "QDSC006": ErrorCodes.QDSC006, "SCJG008": ErrorCodes.SCJG008 } error_config = error_map.get(error_code, ErrorCodes.WJSC008) message = f"{error_config['message']}: {str(original_error)}" return create_http_exception(error_config, message) # 便捷的错误创建函数 class FileUploadErrors: """文件上传接口错误""" @staticmethod def file_missing(): logger.error(ErrorCodes.WJSC001) return create_http_exception(ErrorCodes.WJSC001) @staticmethod def file_multiple(): logger.error(ErrorCodes.WJSC002) return create_http_exception(ErrorCodes.WJSC002) @staticmethod def file_rejected(message: str = None): logger.error(ErrorCodes.WJSC003) return create_http_exception(ErrorCodes.WJSC003, message) @staticmethod def file_format_unsupported(): logger.error(ErrorCodes.WJSC004) return create_http_exception(ErrorCodes.WJSC004) @staticmethod def file_size_exceeded(): logger.error(ErrorCodes.WJSC005) return create_http_exception(ErrorCodes.WJSC005) @staticmethod def project_plan_type_invalid(): logger.error(ErrorCodes.WJSC006) return create_http_exception(ErrorCodes.WJSC006) @staticmethod def unauthorized(): logger.error(ErrorCodes.WJSC007) return create_http_exception(ErrorCodes.WJSC007) @staticmethod def invalid_user(): logger.error(ErrorCodes.WJSC008) return create_http_exception(ErrorCodes.WJSC008) @staticmethod def task_already_exists(): logger.error(ErrorCodes.WJSC010) return create_http_exception(ErrorCodes.WJSC010) @staticmethod def invalid_parameters(): logger.error(ErrorCodes.WJSC009) return create_http_exception(ErrorCodes.WJSC009) @staticmethod def internal_error(original_error: Exception): logger.error(ErrorCodes.WJSC011) return create_server_error("WJSC011", original_error) class LaunchReviewErrors: """启动审查接口错误""" @staticmethod def missing_parameters(): logger.error(ErrorCodes.QDSC001) return create_http_exception(ErrorCodes.QDSC001) @staticmethod def invalid_param_format(): logger.error(ErrorCodes.QDSC002) return create_http_exception(ErrorCodes.QDSC002) @staticmethod def unauthorized(): logger.error(ErrorCodes.QDSC003) return create_http_exception(ErrorCodes.QDSC003) @staticmethod def invalid_user(): logger.error(ErrorCodes.QDSC004) return create_http_exception(ErrorCodes.QDSC004) @staticmethod def task_not_found(): logger.error(ErrorCodes.QDSC005) return create_http_exception(ErrorCodes.QDSC005) @staticmethod def task_already_exists(): logger.error(ErrorCodes.QDSC006) return create_http_exception(ErrorCodes.QDSC006) @staticmethod def project_plan_type_invalid(): logger.error(ErrorCodes.QDSC007) return create_http_exception(ErrorCodes.QDSC007) @staticmethod def enum_type_invalid(): logger.error(ErrorCodes.QDSC008) return create_http_exception(ErrorCodes.QDSC008) @staticmethod def enum_type_cannot_be_null(): logger.error(ErrorCodes.QDSC009) return create_http_exception(ErrorCodes.QDSC009) @staticmethod def file_info_not_found(original_error: Exception): logger.error(ErrorCodes.QDSC010) return create_server_error("QDSC010", original_error) @staticmethod def internal_error(original_error: Exception): logger.error(ErrorCodes.QDSC011) return create_server_error("QDSC011", original_error) @staticmethod def task_not_found_or_expired(): logger.error(ErrorCodes.QDSC012) return create_http_exception(ErrorCodes.QDSC012) @staticmethod def file_info_not_found(): logger.error(ErrorCodes.QDSC013) return create_http_exception(ErrorCodes.QDSC013) class ReviewResultsErrors: """审查结果接口错误""" @staticmethod def invalid_type(): logger.error(ErrorCodes.SCJG001) return create_http_exception(ErrorCodes.SCJG001) @staticmethod def missing_param_id(): logger.error(ErrorCodes.SCJG002) return create_http_exception(ErrorCodes.SCJG002) @staticmethod def invalid_id_format(): logger.error(ErrorCodes.SCJG003) return create_http_exception(ErrorCodes.SCJG003) @staticmethod def unauthorized(): logger.error(ErrorCodes.SCJG004) return create_http_exception(ErrorCodes.SCJG004) @staticmethod def invalid_user(): logger.error(ErrorCodes.SCJG005) return create_http_exception(ErrorCodes.SCJG005) @staticmethod def task_not_found(): logger.error(ErrorCodes.SCJG006) return create_http_exception(ErrorCodes.SCJG006) @staticmethod def no_review_results(): logger.error(ErrorCodes.SCJG007) return create_http_exception(ErrorCodes.SCJG007) @staticmethod def server_error(original_error: Exception): logger.error(ErrorCodes.SCJG008) return create_server_error("SCJG008", original_error)