Files
flutter-template/lib/core/error/failures.dart
T
SkyJourney b8b63282ee fix: 清除 platform-flutter 残留代码,重构文档与开发者体验
P0 代码修复:删除 imSdkAppId、清除内网 IP 与原项目域名、修正 USE_MOCK 默认值
P1 CLAUDE.md 重组:零容忍规则前置,新增 dart-defines 字段对照表
P2 文档优化:先跑再配的 setup 流程,新增 architecture.md 架构图
2026-05-14 13:21:06 +08:00

135 lines
3.5 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'package:sunny_mochi/core/error/exception_mapper.dart'
show ExceptionMapper;
/// 应用层统一失败模型。
///
/// 所有数据/网络/缓存层的异常通过 [ExceptionMapper] 转换为 [Failure] 子类,
/// presentation 层只面对 Failure,避免散落 try-catch DioException / DriftException。
///
/// **实现 [Exception]**:让 datasource/repository 可以直接 `throw failure;`
/// 不触发 `only_throw_errors` lint。
///
sealed class Failure implements Exception {
const Failure({required this.message, this.cause, this.stackTrace});
final String message;
final Object? cause;
final StackTrace? stackTrace;
/// 子类自我描述前缀(避免直接用 [Object.runtimeType]Release 混淆友好)。
String get _typeName;
/// 适合展示给用户的文案(区别于 [message],后者含技术细节,供 Sentry/Talker 日志使用)。
String get userMessage;
@override
String toString() => '$_typeName: $message';
}
/// 网络层失败:超时 / 无网 / DNS 解析失败 / 证书绑定失败 / 连接断开。
class NetworkFailure extends Failure {
const NetworkFailure({
required super.message,
this.kind = NetworkFailureKind.unknown,
super.cause,
super.stackTrace,
});
final NetworkFailureKind kind;
@override
String get _typeName => 'NetworkFailure';
@override
String get userMessage => message;
}
enum NetworkFailureKind {
timeout,
noNetwork,
badCertificate,
cancelled,
unknown,
}
/// 鉴权失败:未登录 / Token 过期 / refresh 失败 → 应跳登录。
class AuthFailure extends Failure {
const AuthFailure({
required super.message,
this.kind = AuthFailureKind.unauthorized,
super.cause,
super.stackTrace,
});
final AuthFailureKind kind;
@override
String get _typeName => 'AuthFailure';
@override
String get userMessage => message;
}
enum AuthFailureKind {
unauthorized, // A0401
forbidden, // 403
refreshFailed,
cryptoFailed, // 客户端加密失败(如登录密码 RSA 加密前置错)
}
/// 服务端业务失败:500/501 / 业务校验失败 / 参数错误。
class ServerFailure extends Failure {
const ServerFailure({
required super.message,
this.code,
this.statusCode,
super.cause,
super.stackTrace,
});
final String? code; // 业务错误码(如 A0500 / A0400 / A0404
final int? statusCode; // HTTP 状态码
@override
String get _typeName => 'ServerFailure';
@override
String get userMessage {
// HTTP 5xx:服务端内部错误,后端 message 可能含技术细节(SQL/堆栈),统一遮蔽
if (statusCode != null && statusCode! >= 500) return '服务器开小差了,请稍后再试';
// 业务码 / 4xxmessage 已经过 ResponseCode.friendlyMessage 映射,安全展示
return message;
}
}
/// 本地缓存/数据库失败:Drift 异常 / SQLCipher 解密失败 / 文件 IO 错误。
class CacheFailure extends Failure {
const CacheFailure({
required super.message,
super.cause,
super.stackTrace,
});
@override
String get _typeName => 'CacheFailure';
@override
String get userMessage => '本地数据异常,请重启应用试试';
}
/// 兜底未知错误。
class UnknownFailure extends Failure {
const UnknownFailure({
required super.message,
super.cause,
super.stackTrace,
});
@override
String get _typeName => 'UnknownFailure';
@override
String get userMessage => '遇到了点问题,已自动上报';
}