/// 데이터 레이어 예외 클래스들 /// /// API, 데이터베이스, 파싱 관련 예외를 정의합니다. import 'app_exceptions.dart'; /// API 예외 기본 클래스 abstract class ApiException extends DataException { final int? statusCode; const ApiException({ required String message, this.statusCode, String? code, dynamic originalError, }) : super( message: message, code: code, originalError: originalError, ); @override String toString() => '$runtimeType: $message${statusCode != null ? ' (HTTP $statusCode)' : ''}'; } /// 네이버 API 예외 class NaverApiException extends ApiException { const NaverApiException({ required String message, int? statusCode, String? code, dynamic originalError, }) : super( message: message, statusCode: statusCode, code: code, originalError: originalError, ); } /// HTML 파싱 예외 class HtmlParsingException extends DataException { final String? url; const HtmlParsingException({ required String message, this.url, dynamic originalError, }) : super( message: message, code: 'HTML_PARSE_ERROR', originalError: originalError, ); @override String toString() { final base = super.toString(); return url != null ? '$base (URL: $url)' : base; } } /// 데이터 변환 예외 class DataConversionException extends DataException { final String fromType; final String toType; const DataConversionException({ required String message, required this.fromType, required this.toType, dynamic originalError, }) : super( message: message, code: 'DATA_CONVERSION_ERROR', originalError: originalError, ); @override String toString() => '$runtimeType: $message ($fromType → $toType)'; } /// 캐시 예외 class CacheException extends StorageException { const CacheException({ required String message, String? code, dynamic originalError, }) : super( message: message, code: code ?? 'CACHE_ERROR', originalError: originalError, ); } /// Hive 예외 class HiveException extends StorageException { const HiveException({ required String message, String? code, dynamic originalError, }) : super( message: message, code: code ?? 'HIVE_ERROR', originalError: originalError, ); } /// URL 처리 예외 class UrlProcessingException extends DataException { final String url; const UrlProcessingException({ required String message, required this.url, String? code, dynamic originalError, }) : super( message: message, code: code ?? 'URL_PROCESSING_ERROR', originalError: originalError, ); @override String toString() => '$runtimeType: $message (URL: $url)'; } /// 잘못된 URL 형식 예외 class InvalidUrlException extends UrlProcessingException { const InvalidUrlException({ required String url, String? message, }) : super( message: message ?? '올바르지 않은 URL 형식입니다', url: url, code: 'INVALID_URL', ); } /// 지원하지 않는 URL 예외 class UnsupportedUrlException extends UrlProcessingException { const UnsupportedUrlException({ required String url, String? message, }) : super( message: message ?? '지원하지 않는 URL입니다', url: url, code: 'UNSUPPORTED_URL', ); }