error_schemas.py 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. """
  2. 施工方案审查API错误码统一定义
  3. 集中管理所有接口的错误码和错误响应格式
  4. """
  5. from typing import Dict, Any
  6. from fastapi import HTTPException
  7. from foundation.logger.loggering import server_logger as logger
  8. class ErrorCodes:
  9. """错误码常量定义"""
  10. # 文件上传接口错误码 (WJSC001-WJSC008)
  11. WJSC001 = {
  12. "code": "WJSC001",
  13. "error_type": "FILE_MISSING",
  14. "message": "未上传文件",
  15. "status_code": 400
  16. }
  17. WJSC002 = {
  18. "code": "WJSC002",
  19. "error_type": "FILE_MULTIPLE",
  20. "message": "仅支持单文件上传",
  21. "status_code": 400
  22. }
  23. WJSC003 = {
  24. "code": "WJSC003",
  25. "error_type": "FILE_REJECTED",
  26. "message": "格式错误、内容违规、文件为空",
  27. "status_code": 400
  28. }
  29. WJSC004 = {
  30. "code": "WJSC004",
  31. "error_type": "FILE_FORMAT_UNSUPPORTED",
  32. "message": "文件格式不支持(仅允许pdf/doc/docx)",
  33. "status_code": 400
  34. }
  35. WJSC005 = {
  36. "code": "WJSC005",
  37. "error_type": "FILE_SIZE_EXCEEDED",
  38. "message": "文件过大(最大不超过30MB)",
  39. "status_code": 400
  40. }
  41. WJSC006 = {
  42. "code": "WJSC006",
  43. "error_type": "PROJECT_PLAN_TYPE_INVALID",
  44. "message": "无效工程方案类型(未提供或未注册)",
  45. "status_code": 400
  46. }
  47. WJSC007 = {
  48. "code": "WJSC007",
  49. "error_type": "UNAUTHORIZED",
  50. "message": "认证失败(未提供或无效的Authorization)",
  51. "status_code": 401
  52. }
  53. WJSC008 = {
  54. "code": "WJSC008",
  55. "error_type": "INVALID_USER",
  56. "message": "用户标识未提供或无效",
  57. "status_code": 403
  58. }
  59. WJSC009 = {
  60. "code": "WJSC009",
  61. "error_type": "CALLBACK_URL_MISS",
  62. "message": "回调客户端地址缺失,请提供回调客户端地址",
  63. "status_code": 403
  64. }
  65. WJSC010 = {
  66. "code": "WJSC010",
  67. "error_type": "TASK_ALREADY_EXISTS",
  68. "message": "任务已存在,请勿重复提交",
  69. "status_code": 409
  70. }
  71. WJSC011 = {
  72. "code": "WJSC011",
  73. "error_type": "INTERNAL_ERROR",
  74. "message": "服务端内部错误",
  75. "status_code": 500
  76. }
  77. # 进度查询接口错误码 (JDLX001-JDLX006)
  78. JDLX001 = {
  79. "code": "JDLX001",
  80. "error_type": "MISSING_PARAMETERS",
  81. "message": "请求参数缺失",
  82. "status_code": 400
  83. }
  84. JDLX002 = {
  85. "code": "JDLX002",
  86. "error_type": "INVALID_PARAM_FORMAT",
  87. "message": "请求参数格式错误",
  88. "status_code": 400
  89. }
  90. JDLX003 = {
  91. "code": "JDLX003",
  92. "error_type": "UNAUTHORIZED",
  93. "message": "认证失败(未提供或无效的Authorization)",
  94. "status_code": 401
  95. }
  96. JDLX004 = {
  97. "code": "JDLX004",
  98. "error_type": "INVALID_USER",
  99. "message": "用户标识未提供或无效",
  100. "status_code": 403
  101. }
  102. JDLX005 = {
  103. "code": "JDLX005",
  104. "error_type": "TASK_NOT_FOUND",
  105. "message": "任务ID不存在或已过期",
  106. "status_code": 404
  107. }
  108. JDLX006 = {
  109. "code": "JDLX006",
  110. "error_type": "SERVER_INTERNAL_ERROR",
  111. "message": "服务端内部错误",
  112. "status_code": 500
  113. }
  114. # 审查结果接口错误码 (SCJG001-SCJG008)
  115. SCJG001 = {
  116. "code": "SCJG001",
  117. "error_type": "INVALID_TYPE",
  118. "message": "结果类型无效(非'summary'或'issues')",
  119. "status_code": 400
  120. }
  121. SCJG002 = {
  122. "code": "SCJG002",
  123. "error_type": "MISSING_PARAM_ID",
  124. "message": "callback_task_id缺失",
  125. "status_code": 400
  126. }
  127. SCJG003 = {
  128. "code": "SCJG003",
  129. "error_type": "INVALID_ID_FORMAT",
  130. "message": "callback_task_id格式错误",
  131. "status_code": 400
  132. }
  133. SCJG004 = {
  134. "code": "SCJG004",
  135. "error_type": "UNAUTHORIZED",
  136. "message": "认证失败(未提供或无效的Authorization)",
  137. "status_code": 401
  138. }
  139. SCJG005 = {
  140. "code": "SCJG005",
  141. "error_type": "INVALID_USER",
  142. "message": "用户标识未提供或无效",
  143. "status_code": 403
  144. }
  145. SCJG006 = {
  146. "code": "SCJG006",
  147. "error_type": "TASK_NOT_FOUND",
  148. "message": "callback_task_id不存在或已过期",
  149. "status_code": 404
  150. }
  151. SCJG007 = {
  152. "code": "SCJG007",
  153. "error_type": "NO_REVIEW_RESULTS",
  154. "message": "无审查结果数据",
  155. "status_code": 404
  156. }
  157. SCJG008 = {
  158. "code": "SCJG008",
  159. "error_type": "SERVER_ERROR",
  160. "message": "服务端内部错误(审查结果生成失败)",
  161. "status_code": 500
  162. }
  163. def create_http_exception(error_code: Dict[str, Any], custom_message: str = None) -> HTTPException:
  164. """
  165. 创建HTTP异常
  166. Args:
  167. error_code: 错误码字典
  168. custom_message: 自定义错误消息,可选
  169. Returns:
  170. HTTPException: FastAPI异常对象
  171. """
  172. detail = {
  173. "code": error_code["code"],
  174. "error_type": error_code["error_type"],
  175. "message": custom_message or error_code["message"]
  176. }
  177. return HTTPException(
  178. status_code=error_code["status_code"],
  179. detail=detail
  180. )
  181. def create_server_error(error_code: str, original_error: Exception) -> HTTPException:
  182. """
  183. 创建服务器内部错误异常
  184. Args:
  185. error_code: 错误码 (如 "WJSC008", "JDLX006", "SCJG008")
  186. original_error: 原始异常
  187. Returns:
  188. HTTPException: FastAPI异常对象
  189. """
  190. error_map = {
  191. "WJSC011": ErrorCodes.WJSC011,
  192. "JDLX006": ErrorCodes.JDLX006,
  193. "SCJG008": ErrorCodes.SCJG008
  194. }
  195. error_config = error_map.get(error_code, ErrorCodes.WJSC008)
  196. message = f"{error_config['message']}: {str(original_error)}"
  197. return create_http_exception(error_config, message)
  198. # 便捷的错误创建函数
  199. class FileUploadErrors:
  200. """文件上传接口错误"""
  201. @staticmethod
  202. def file_missing():
  203. logger.error(ErrorCodes.WJSC001)
  204. return create_http_exception(ErrorCodes.WJSC001)
  205. @staticmethod
  206. def file_multiple():
  207. logger.error(ErrorCodes.WJSC002)
  208. return create_http_exception(ErrorCodes.WJSC002)
  209. @staticmethod
  210. def file_rejected(message: str = None):
  211. logger.error(ErrorCodes.WJSC003)
  212. return create_http_exception(ErrorCodes.WJSC003, message)
  213. @staticmethod
  214. def file_format_unsupported():
  215. logger.error(ErrorCodes.WJSC004)
  216. return create_http_exception(ErrorCodes.WJSC004)
  217. @staticmethod
  218. def file_size_exceeded():
  219. logger.error(ErrorCodes.WJSC005)
  220. return create_http_exception(ErrorCodes.WJSC005)
  221. @staticmethod
  222. def project_plan_type_invalid():
  223. logger.error(ErrorCodes.WJSC006)
  224. return create_http_exception(ErrorCodes.WJSC006)
  225. @staticmethod
  226. def unauthorized():
  227. logger.error(ErrorCodes.WJSC007)
  228. return create_http_exception(ErrorCodes.WJSC007)
  229. @staticmethod
  230. def invalid_user():
  231. logger.error(ErrorCodes.WJSC008)
  232. return create_http_exception(ErrorCodes.WJSC008)
  233. @staticmethod
  234. def callback_url_missing():
  235. logger.error(ErrorCodes.WJSC009)
  236. return create_http_exception(ErrorCodes.WJSC009)
  237. @staticmethod
  238. def task_already_exists():
  239. logger.error(ErrorCodes.WJSC010)
  240. return create_http_exception(ErrorCodes.WJSC010)
  241. @staticmethod
  242. def internal_error(original_error: Exception):
  243. logger.error(ErrorCodes.WJSC011)
  244. return create_server_error("WJSC011", original_error)
  245. class TaskProgressErrors:
  246. """进度查询接口错误"""
  247. @staticmethod
  248. def missing_parameters():
  249. logger.error(ErrorCodes.JDLX001)
  250. return create_http_exception(ErrorCodes.JDLX001)
  251. @staticmethod
  252. def invalid_param_format():
  253. logger.error(ErrorCodes.JDLX002)
  254. return create_http_exception(ErrorCodes.JDLX002)
  255. @staticmethod
  256. def unauthorized():
  257. logger.error(ErrorCodes.JDLX003)
  258. return create_http_exception(ErrorCodes.JDLX003)
  259. @staticmethod
  260. def invalid_user():
  261. logger.error(ErrorCodes.JDLX004)
  262. return create_http_exception(ErrorCodes.JDLX004)
  263. @staticmethod
  264. def task_not_found():
  265. logger.error(ErrorCodes.JDLX005)
  266. return create_http_exception(ErrorCodes.JDLX005)
  267. @staticmethod
  268. def server_internal_error(original_error: Exception):
  269. logger.error(ErrorCodes.JDLX006, original_error)
  270. return create_server_error("JDLX006", original_error)
  271. class ReviewResultsErrors:
  272. """审查结果接口错误"""
  273. @staticmethod
  274. def invalid_type():
  275. logger.error(ErrorCodes.SCJG001)
  276. return create_http_exception(ErrorCodes.SCJG001)
  277. @staticmethod
  278. def missing_param_id():
  279. logger.error(ErrorCodes.SCJG002)
  280. return create_http_exception(ErrorCodes.SCJG002)
  281. @staticmethod
  282. def invalid_id_format():
  283. logger.error(ErrorCodes.SCJG003)
  284. return create_http_exception(ErrorCodes.SCJG003)
  285. @staticmethod
  286. def unauthorized():
  287. logger.error(ErrorCodes.SCJG004)
  288. return create_http_exception(ErrorCodes.SCJG004)
  289. @staticmethod
  290. def invalid_user():
  291. logger.error(ErrorCodes.SCJG005)
  292. return create_http_exception(ErrorCodes.SCJG005)
  293. @staticmethod
  294. def task_not_found():
  295. logger.error(ErrorCodes.SCJG006)
  296. return create_http_exception(ErrorCodes.SCJG006)
  297. @staticmethod
  298. def no_review_results():
  299. logger.error(ErrorCodes.SCJG007)
  300. return create_http_exception(ErrorCodes.SCJG007)
  301. @staticmethod
  302. def server_error(original_error: Exception):
  303. logger.error(ErrorCodes.SCJG008)
  304. return create_server_error("SCJG008", original_error)