import 'package:patbond_flutter/core/network/api_exception.dart'; /// community / media 域类型化业务异常(契约 v1.3.0 定型的 9 个新错误码, /// 20 号收口报告 §1;40902 乐观锁与 pets 域共码,本域映射为独立类型)。 /// 全部继承 [ApiBusinessException],既有按基类捕获的通用错误处理不受影响。 /// 40301:对可见帖子/评论无相应操作权限(改删他人已发布帖、 /// 删他人可见评论——含帖主删他人评论,D3-7 首版不做)。 final class PostAccessDeniedException extends ApiBusinessException { const PostAccessDeniedException({required super.message}) : super(code: ApiCodes.postAccessDenied); } /// 40403:帖子不存在 / 已软删 / hidden/archived(含作者)/ 他人 draft /// (防枚举,全部情况响应完全一致;互动路径上含作者本人草稿)。 final class PostNotFoundException extends ApiBusinessException { const PostNotFoundException({required super.message}) : super(code: ApiCodes.postNotFound); } /// 40404:评论不存在、已删或所属帖子不可见(防枚举合并)。 final class CommentNotFoundException extends ApiBusinessException { const CommentNotFoundException({required super.message}) : super(code: ApiCodes.commentNotFound); } /// 40405:media asset 不存在、非本人所有或已删(防枚举合并)。 final class MediaAssetNotFoundException extends ApiBusinessException { const MediaAssetNotFoundException({required super.message}) : super(code: ApiCodes.mediaNotFound); } /// 40406:目标用户不存在或已注销(合并不泄露成因)。 final class CommunityUserNotFoundException extends ApiBusinessException { const CommunityUserNotFoundException({required super.message}) : super(code: ApiCodes.communityUserNotFound); } /// 40902:帖子编辑乐观锁版本冲突(version 过期)。 /// 客户端处理:刷新详情取新 version 后重提。 final class PostVersionConflictException extends ApiBusinessException { const PostVersionConflictException({required super.message}) : super(code: ApiCodes.versionConflict); } /// 40905:同 Idempotency-Key 不同 payload(规范化 request_hash 不符)。 /// 客户端每次逻辑提交应换新键,重试间保持不变。 final class IdempotencyMismatchException extends ApiBusinessException { const IdempotencyMismatchException({required super.message}) : super(code: ApiCodes.idempotencyKeyMismatch); } /// 42203:引用了本人所有但非 ready(uploading/failed)状态的 asset。 final class MediaNotReadyException extends ApiBusinessException { const MediaNotReadyException({required super.message}) : super(code: ApiCodes.mediaNotReady); } /// 42204:自关注(仅 PUT;自取关走 DELETE 的 200 幂等 no-op)。 final class SelfFollowException extends ApiBusinessException { const SelfFollowException({required super.message}) : super(code: ApiCodes.selfFollow); } /// 42205:上传状态不允许确认——对象未上传(保持 uploading 可重试)、 /// 大小/类型不符(置 failed 终态)、failed 态再确认(已 ready 幂等 200 除外)。 final class MediaUploadStateException extends ApiBusinessException { const MediaUploadStateException({required super.message}) : super(code: ApiCodes.mediaUploadStateInvalid); } /// 把通用业务异常按 community/media 域错误码升格为类型化异常; /// 未覆盖的码(40000 参数错误、40401 宠物防枚举等)原样返回,沿用通用处理。 ApiBusinessException mapCommunityBusinessException(ApiBusinessException error) { return switch (error.code) { ApiCodes.postAccessDenied => PostAccessDeniedException( message: error.message, ), ApiCodes.postNotFound => PostNotFoundException(message: error.message), ApiCodes.commentNotFound => CommentNotFoundException( message: error.message, ), ApiCodes.mediaNotFound => MediaAssetNotFoundException( message: error.message, ), ApiCodes.communityUserNotFound => CommunityUserNotFoundException( message: error.message, ), ApiCodes.versionConflict => PostVersionConflictException( message: error.message, ), ApiCodes.idempotencyKeyMismatch => IdempotencyMismatchException( message: error.message, ), ApiCodes.mediaNotReady => MediaNotReadyException(message: error.message), ApiCodes.selfFollow => SelfFollowException(message: error.message), ApiCodes.mediaUploadStateInvalid => MediaUploadStateException( message: error.message, ), _ => error, }; }