error_schemas.py 8.4 KB

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