312 lines
9.8 KiB
Dart
312 lines
9.8 KiB
Dart
/// Custom exceptions for the Worker app
|
|
///
|
|
/// This file defines all custom exception types used throughout the application
|
|
/// for better error handling and user feedback.
|
|
library;
|
|
|
|
// ============================================================================
|
|
// Network Exceptions
|
|
// ============================================================================
|
|
|
|
/// Base exception for all network-related errors
|
|
class NetworkException implements Exception {
|
|
const NetworkException(this.message, {this.statusCode, this.data});
|
|
|
|
final String message;
|
|
final int? statusCode;
|
|
final dynamic data;
|
|
|
|
@override
|
|
String toString() =>
|
|
'NetworkException: $message${statusCode != null ? ' (Status: $statusCode)' : ''}';
|
|
}
|
|
|
|
/// Exception thrown when there's no internet connection
|
|
class NoInternetException extends NetworkException {
|
|
const NoInternetException()
|
|
: super('Không có kết nối internet. Vui lòng kiểm tra kết nối của bạn.');
|
|
}
|
|
|
|
/// Exception thrown when connection times out
|
|
class TimeoutException extends NetworkException {
|
|
const TimeoutException()
|
|
: super('Kết nối quá lâu. Vui lòng thử lại.', statusCode: 408);
|
|
}
|
|
|
|
/// Exception thrown when server returns 500+ errors
|
|
class ServerException extends NetworkException {
|
|
const ServerException([
|
|
String message = 'Lỗi máy chủ. Vui lòng thử lại sau.',
|
|
int? statusCode,
|
|
]) : super(message, statusCode: statusCode);
|
|
}
|
|
|
|
/// Exception thrown when server is unreachable
|
|
class ServiceUnavailableException extends ServerException {
|
|
const ServiceUnavailableException()
|
|
: super('Dịch vụ tạm thời không khả dụng. Vui lòng thử lại sau.', 503);
|
|
}
|
|
|
|
// ============================================================================
|
|
// Authentication Exceptions
|
|
// ============================================================================
|
|
|
|
/// Base exception for authentication-related errors
|
|
class AuthException implements Exception {
|
|
const AuthException(this.message, {this.statusCode});
|
|
|
|
final String message;
|
|
final int? statusCode;
|
|
|
|
@override
|
|
String toString() => 'AuthException: $message';
|
|
}
|
|
|
|
/// Exception thrown when authentication credentials are invalid
|
|
class InvalidCredentialsException extends AuthException {
|
|
const InvalidCredentialsException()
|
|
: super('Thông tin đăng nhập không hợp lệ.', statusCode: 401);
|
|
}
|
|
|
|
/// Exception thrown when user is not authenticated
|
|
class UnauthorizedException extends AuthException {
|
|
const UnauthorizedException([
|
|
super.message = 'Phiên đăng nhập hết hạn. Vui lòng đăng nhập lại.',
|
|
]) : super(statusCode: 401);
|
|
}
|
|
|
|
/// Exception thrown when user doesn't have permission
|
|
class ForbiddenException extends AuthException {
|
|
const ForbiddenException()
|
|
: super('Bạn không có quyền truy cập tài nguyên này.', statusCode: 403);
|
|
}
|
|
|
|
/// Exception thrown when auth token is expired
|
|
class TokenExpiredException extends AuthException {
|
|
const TokenExpiredException()
|
|
: super(
|
|
'Phiên đăng nhập hết hạn. Vui lòng đăng nhập lại.',
|
|
statusCode: 401,
|
|
);
|
|
}
|
|
|
|
/// Exception thrown when refresh token is invalid
|
|
class InvalidRefreshTokenException extends AuthException {
|
|
const InvalidRefreshTokenException()
|
|
: super(
|
|
'Không thể làm mới phiên đăng nhập. Vui lòng đăng nhập lại.',
|
|
statusCode: 401,
|
|
);
|
|
}
|
|
|
|
/// Exception thrown when OTP is invalid
|
|
class InvalidOTPException extends AuthException {
|
|
const InvalidOTPException()
|
|
: super('Mã OTP không hợp lệ. Vui lòng thử lại.', statusCode: 400);
|
|
}
|
|
|
|
/// Exception thrown when OTP is expired
|
|
class OTPExpiredException extends AuthException {
|
|
const OTPExpiredException()
|
|
: super('Mã OTP đã hết hạn. Vui lòng yêu cầu mã mới.', statusCode: 400);
|
|
}
|
|
|
|
// ============================================================================
|
|
// Request Validation Exceptions
|
|
// ============================================================================
|
|
|
|
/// Exception thrown when request data is invalid
|
|
class ValidationException implements Exception {
|
|
const ValidationException(this.message, {this.errors});
|
|
|
|
final String message;
|
|
final Map<String, List<String>>? errors;
|
|
|
|
@override
|
|
String toString() {
|
|
if (errors != null && errors!.isNotEmpty) {
|
|
final errorMessages = errors!.entries
|
|
.map((e) => '${e.key}: ${e.value.join(", ")}')
|
|
.join('; ');
|
|
return 'ValidationException: $message - $errorMessages';
|
|
}
|
|
return 'ValidationException: $message';
|
|
}
|
|
}
|
|
|
|
/// Exception thrown when request parameters are invalid
|
|
class BadRequestException extends ValidationException {
|
|
const BadRequestException([
|
|
String message = 'Yêu cầu không hợp lệ.',
|
|
Map<String, List<String>>? errors,
|
|
]) : super(message, errors: errors);
|
|
}
|
|
|
|
// ============================================================================
|
|
// Resource Exceptions
|
|
// ============================================================================
|
|
|
|
/// Exception thrown when requested resource is not found
|
|
class NotFoundException implements Exception {
|
|
const NotFoundException([
|
|
this.message = 'Không tìm thấy tài nguyên.',
|
|
this.resourceType,
|
|
this.resourceId,
|
|
]);
|
|
|
|
final String message;
|
|
final String? resourceType;
|
|
final String? resourceId;
|
|
|
|
@override
|
|
String toString() {
|
|
if (resourceType != null && resourceId != null) {
|
|
return 'NotFoundException: $resourceType with ID $resourceId not found';
|
|
}
|
|
return 'NotFoundException: $message';
|
|
}
|
|
}
|
|
|
|
/// Exception thrown when trying to create a duplicate resource
|
|
class ConflictException implements Exception {
|
|
const ConflictException([this.message = 'Tài nguyên đã tồn tại.']);
|
|
|
|
final String message;
|
|
|
|
@override
|
|
String toString() => 'ConflictException: $message';
|
|
}
|
|
|
|
// ============================================================================
|
|
// Rate Limiting Exceptions
|
|
// ============================================================================
|
|
|
|
/// Exception thrown when API rate limit is exceeded
|
|
class RateLimitException implements Exception {
|
|
const RateLimitException([
|
|
this.message = 'Bạn đã gửi quá nhiều yêu cầu. Vui lòng thử lại sau.',
|
|
this.retryAfter,
|
|
]);
|
|
|
|
final String message;
|
|
final int? retryAfter; // seconds
|
|
|
|
@override
|
|
String toString() {
|
|
if (retryAfter != null) {
|
|
return 'RateLimitException: $message (Retry after: ${retryAfter}s)';
|
|
}
|
|
return 'RateLimitException: $message';
|
|
}
|
|
}
|
|
|
|
// ============================================================================
|
|
// Payment Exceptions
|
|
// ============================================================================
|
|
|
|
/// Exception thrown for payment-related errors
|
|
class PaymentException implements Exception {
|
|
const PaymentException(this.message, {this.transactionId});
|
|
|
|
final String message;
|
|
final String? transactionId;
|
|
|
|
@override
|
|
String toString() => 'PaymentException: $message';
|
|
}
|
|
|
|
/// Exception thrown when payment fails
|
|
class PaymentFailedException extends PaymentException {
|
|
const PaymentFailedException([
|
|
String message = 'Thanh toán thất bại. Vui lòng thử lại.',
|
|
String? transactionId,
|
|
]) : super(message, transactionId: transactionId);
|
|
}
|
|
|
|
/// Exception thrown when payment is cancelled
|
|
class PaymentCancelledException extends PaymentException {
|
|
const PaymentCancelledException() : super('Thanh toán đã bị hủy.');
|
|
}
|
|
|
|
// ============================================================================
|
|
// Cache Exceptions
|
|
// ============================================================================
|
|
|
|
/// Exception thrown for cache-related errors
|
|
class CacheException implements Exception {
|
|
const CacheException([this.message = 'Lỗi khi truy cập bộ nhớ đệm.']);
|
|
|
|
final String message;
|
|
|
|
@override
|
|
String toString() => 'CacheException: $message';
|
|
}
|
|
|
|
/// Exception thrown when cache data is corrupted
|
|
class CacheCorruptedException extends CacheException {
|
|
const CacheCorruptedException() : super('Dữ liệu bộ nhớ đệm bị hỏng.');
|
|
}
|
|
|
|
// ============================================================================
|
|
// Storage Exceptions
|
|
// ============================================================================
|
|
|
|
/// Exception thrown for local storage errors
|
|
class StorageException implements Exception {
|
|
const StorageException([this.message = 'Lỗi khi truy cập bộ nhớ cục bộ.']);
|
|
|
|
final String message;
|
|
|
|
@override
|
|
String toString() => 'StorageException: $message';
|
|
}
|
|
|
|
/// Exception thrown when storage is full
|
|
class StorageFullException extends StorageException {
|
|
const StorageFullException()
|
|
: super('Bộ nhớ đã đầy. Vui lòng giải phóng không gian.');
|
|
}
|
|
|
|
// ============================================================================
|
|
// Parse Exceptions
|
|
// ============================================================================
|
|
|
|
/// Exception thrown when JSON parsing fails
|
|
class ParseException implements Exception {
|
|
const ParseException([
|
|
this.message = 'Lỗi khi phân tích dữ liệu.',
|
|
this.source,
|
|
]);
|
|
|
|
final String message;
|
|
final dynamic source;
|
|
|
|
@override
|
|
String toString() => 'ParseException: $message';
|
|
}
|
|
|
|
// ============================================================================
|
|
// Unknown Exceptions
|
|
// ============================================================================
|
|
|
|
/// Exception thrown for unexpected errors
|
|
class UnknownException implements Exception {
|
|
const UnknownException([
|
|
this.message = 'Đã xảy ra lỗi không xác định.',
|
|
this.originalError,
|
|
this.stackTrace,
|
|
]);
|
|
|
|
final String message;
|
|
final dynamic originalError;
|
|
final StackTrace? stackTrace;
|
|
|
|
@override
|
|
String toString() {
|
|
if (originalError != null) {
|
|
return 'UnknownException: $message (Original: $originalError)';
|
|
}
|
|
return 'UnknownException: $message';
|
|
}
|
|
}
|