/// Base class for all exceptions in the application /// Exceptions are thrown during runtime and should be caught and converted to failures abstract class AppException implements Exception { final String message; final String? code; const AppException(this.message, {this.code}); @override String toString() => 'AppException: $message${code != null ? ' (Code: $code)' : ''}'; } /// Exception thrown when there's a server-related error /// This includes HTTP errors, API response errors, etc. class ServerException extends AppException { const ServerException(super.message, {super.code}); @override String toString() => 'ServerException: $message${code != null ? ' (Code: $code)' : ''}'; } /// Exception thrown when there's a network-related error /// This includes connection timeouts, no internet connection, etc. class NetworkException extends AppException { const NetworkException(super.message, {super.code}); @override String toString() => 'NetworkException: $message${code != null ? ' (Code: $code)' : ''}'; } /// Exception thrown when there's a local storage error /// This includes Hive errors, file system errors, etc. class CacheException extends AppException { const CacheException(super.message, {super.code}); @override String toString() => 'CacheException: $message${code != null ? ' (Code: $code)' : ''}'; } /// Exception thrown when input validation fails class ValidationException extends AppException { final Map? fieldErrors; const ValidationException( super.message, { super.code, this.fieldErrors, }); @override String toString() { var result = 'ValidationException: $message${code != null ? ' (Code: $code)' : ''}'; if (fieldErrors != null && fieldErrors!.isNotEmpty) { result += '\nField errors: ${fieldErrors.toString()}'; } return result; } } /// Exception thrown when a required permission is denied class PermissionException extends AppException { final String permissionType; const PermissionException( super.message, this.permissionType, { super.code, }); @override String toString() => 'PermissionException: $message (Permission: $permissionType)${code != null ? ' (Code: $code)' : ''}'; } /// Exception thrown when scanning operation fails class ScannerException extends AppException { const ScannerException(super.message, {super.code}); @override String toString() => 'ScannerException: $message${code != null ? ' (Code: $code)' : ''}'; } /// Exception thrown when printing operation fails class PrintException extends AppException { const PrintException(super.message, {super.code}); @override String toString() => 'PrintException: $message${code != null ? ' (Code: $code)' : ''}'; } /// Exception thrown for JSON parsing errors class JsonException extends AppException { const JsonException(super.message, {super.code}); @override String toString() => 'JsonException: $message${code != null ? ' (Code: $code)' : ''}'; } /// Exception thrown for format-related errors (e.g., invalid barcode format) class FormatException extends AppException { final String expectedFormat; final String receivedFormat; const FormatException( super.message, this.expectedFormat, this.receivedFormat, { super.code, }); @override String toString() => 'FormatException: $message (Expected: $expectedFormat, Received: $receivedFormat)${code != null ? ' (Code: $code)' : ''}'; } /// Generic exception for unexpected errors class UnknownException extends AppException { const UnknownException([super.message = 'An unexpected error occurred', String? code]) : super(code: code); @override String toString() => 'UnknownException: $message${code != null ? ' (Code: $code)' : ''}'; }