S8BizException.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. namespace Admin.NET.Plugin.AiDOP.Service.S8;
  2. /// <summary>S8 业务规则异常,由 Controller 捕获后返回 400。</summary>
  3. public class S8BizException : Exception
  4. {
  5. public S8BizException(string message) : base(message) { }
  6. }
  7. /// <summary>
  8. /// S8-TENANT-FACTORY-P0-CLOSURE-1:目标资源在当前可信作用域内不存在(不存在,或属于其它租户 / 工厂)。
  9. /// 由 Controller 捕获后统一返回 404——对越权 Id 与不存在 Id 给出同一响应,
  10. /// 不泄露「他租户存在该资源」。继承 <see cref="S8BizException"/>,
  11. /// 使既有只捕获 S8BizException 的调用方仍能安全降级为 400,而不是 500。
  12. /// </summary>
  13. public sealed class S8NotFoundException : S8BizException
  14. {
  15. public S8NotFoundException(string message = "记录不存在") : base(message) { }
  16. }
  17. /// <summary>
  18. /// S8-STEP6D-CFG-ALERT-LEGACY-WRITE-GUARD-CERT-1:该配置对象已转为历史兼容只读,写入口已退役。
  19. /// 由 Controller 捕获后返回 <b>410 Gone</b>——语义是「该能力曾经存在、现已永久退役」,
  20. /// 区别于 400(入参不合法,改对了还能存)与 404(找不到,换个 Id 还能存)。
  21. ///
  22. /// 继承 <see cref="S8BizException"/>,与 <see cref="S8NotFoundException"/> 同理:
  23. /// 使既有只捕获 S8BizException 的调用方安全降级为 400,而不是 500。
  24. /// ⚠️ Controller 的 catch 顺序必须把本类型排在 S8BizException 之前,否则会被基类先吞掉降级成 400。
  25. ///
  26. /// <see cref="UserMessage"/> 是**固定文案**,供 Controller 直接返回;
  27. /// 不要把 ex.Message 以外的内部信息(异常类型名 / 堆栈 / SQL)暴露给前端。
  28. /// </summary>
  29. public sealed class S8WriteRetiredException : S8BizException
  30. {
  31. /// <summary>
  32. /// CFG_ALERT 的退役文案(默认值,保持既有调用方与测试引用不变):
  33. /// 说明只读原因 + 指出当前真正的运行时权威。
  34. /// </summary>
  35. public const string UserMessage =
  36. "告警规则已转为历史兼容只读配置,当前运行时告警判定由监控规则管理。";
  37. /// <summary>
  38. /// S8-STEP6E-CFG-WATCH-FIX-AND-SAFE-CERT-1:CFG_WATCH 通用整实体 PUT 的退役文案。
  39. ///
  40. /// 与 CFG_ALERT 的语义不同——监控规则本身**仍是生产权威**,退役的只是那个会连带
  41. /// 暴露 scheduler-owned 运行时列(lock_token / lock_until / paused_until / next_run_at /
  42. /// last_* / consecutive_failure_count)的整实体更新入口。正式配置修改仍走窄写入口。
  43. /// 故文案必须引导用户去专用接口,而不能让人误以为「监控规则整体只读了」。
  44. /// </summary>
  45. public const string WatchRuleUpdateMessage =
  46. "监控规则通用整实体更新接口已退役,请使用监控规则的专用配置接口。";
  47. /// <summary>
  48. /// S8-RULE-GOVERNANCE-BATCH3:业务侧建规则入口的退役文案。
  49. ///
  50. /// 与 <see cref="WatchRuleUpdateMessage"/> 的区别:那条退役的是"整实体更新"这种**形式**,
  51. /// 规则本身仍可配置;本条退役的是"创建规则"这件**事**本身 ——
  52. /// 规则的业务语义现在由系统版本(代码定义)决定,任何调用方都不该能凭空造出一条规则。
  53. /// 文案必须说清"去哪里要新规则",否则用户只会以为接口坏了。
  54. /// </summary>
  55. public const string WatchRuleCreateMessage =
  56. "监控规则由系统版本定义,不支持通过接口创建;新规则随版本发布后会自动为各租户建立运行策略。";
  57. /// <summary>
  58. /// S8-RULE-GOVERNANCE-BATCH3:业务侧删规则入口的退役文案。
  59. ///
  60. /// 规则定义的生命周期属于代码版本,运行策略行的删除同样不该由页面触发。
  61. /// 用户"不想用这条规则"的正确表达是**停用**,不是删除 ——
  62. /// 删除会连带丢掉该租户已经调好的参数与运行历史,且下次供给对账又会把它建回来。
  63. /// </summary>
  64. public const string WatchRuleDeleteMessage =
  65. "监控规则由系统版本定义,不支持删除;如需停止该规则,请将其停用。";
  66. /// <summary>
  67. /// S8-RULE-GOVERNANCE-BATCH3:配置向导草稿整体退役的文案。
  68. /// 草稿的唯一出口是"生成规则",而创建规则这件事已经不存在,草稿也就失去了全部意义。
  69. /// </summary>
  70. public const string ConfigDraftRetiredMessage =
  71. "配置向导已下线:监控规则由系统版本定义,不再通过向导创建。";
  72. public S8WriteRetiredException() : base(UserMessage) { }
  73. /// <summary>按写入口给出各自的固定文案;调用方只能传预定义常量,不得拼入内部实现细节。</summary>
  74. public S8WriteRetiredException(string userMessage) : base(userMessage) { }
  75. }