128 lines
3.0 KiB
Dart
128 lines
3.0 KiB
Dart
/// Base exception type for backend-facing failures.
|
|
sealed class BackendException implements Exception {
|
|
const BackendException(
|
|
this.message, {
|
|
this.statusCode,
|
|
this.requestId,
|
|
this.backendCode,
|
|
});
|
|
|
|
/// Human-readable message suitable for diagnostics.
|
|
final String message;
|
|
|
|
/// HTTP status code if available.
|
|
final int? statusCode;
|
|
|
|
/// Correlation/request identifier emitted by backend or gateway.
|
|
final String? requestId;
|
|
|
|
/// Structured backend error code if provided by server.
|
|
final String? backendCode;
|
|
|
|
@override
|
|
String toString() {
|
|
return 'BackendException(message: $message, statusCode: $statusCode, '
|
|
'requestId: $requestId, backendCode: $backendCode)';
|
|
}
|
|
}
|
|
|
|
/// No HTTP response was received due to connectivity issues.
|
|
final class NetworkException extends BackendException {
|
|
const NetworkException(
|
|
super.message, {
|
|
super.statusCode,
|
|
super.requestId,
|
|
super.backendCode,
|
|
});
|
|
}
|
|
|
|
/// Request timed out at connect/send/receive stage.
|
|
final class TimeoutException extends BackendException {
|
|
const TimeoutException(
|
|
super.message, {
|
|
super.statusCode,
|
|
super.requestId,
|
|
super.backendCode,
|
|
});
|
|
}
|
|
|
|
/// Backend rejected request due to missing/invalid auth.
|
|
class UnauthorizedException extends BackendException {
|
|
const UnauthorizedException(
|
|
super.message, {
|
|
super.statusCode,
|
|
super.requestId,
|
|
super.backendCode,
|
|
});
|
|
}
|
|
|
|
/// Session is no longer valid and refresh failed.
|
|
final class AuthExpiredException extends UnauthorizedException {
|
|
const AuthExpiredException(
|
|
super.message, {
|
|
super.statusCode,
|
|
super.requestId,
|
|
super.backendCode,
|
|
});
|
|
}
|
|
|
|
/// Caller is authenticated but lacks permissions.
|
|
final class ForbiddenException extends BackendException {
|
|
const ForbiddenException(
|
|
super.message, {
|
|
super.statusCode,
|
|
super.requestId,
|
|
super.backendCode,
|
|
});
|
|
}
|
|
|
|
/// Resource was not found.
|
|
final class NotFoundException extends BackendException {
|
|
const NotFoundException(
|
|
super.message, {
|
|
super.statusCode,
|
|
super.requestId,
|
|
super.backendCode,
|
|
});
|
|
}
|
|
|
|
/// Backend rate-limited the request.
|
|
final class RateLimitedException extends BackendException {
|
|
const RateLimitedException(
|
|
super.message, {
|
|
super.statusCode,
|
|
super.requestId,
|
|
super.backendCode,
|
|
});
|
|
}
|
|
|
|
/// 5xx backend failure.
|
|
final class ServerException extends BackendException {
|
|
const ServerException(
|
|
super.message, {
|
|
super.statusCode,
|
|
super.requestId,
|
|
super.backendCode,
|
|
});
|
|
}
|
|
|
|
/// Request was syntactically valid but semantically invalid.
|
|
final class ValidationException extends BackendException {
|
|
const ValidationException(
|
|
super.message, {
|
|
super.statusCode,
|
|
super.requestId,
|
|
super.backendCode,
|
|
});
|
|
}
|
|
|
|
/// Fallback for failures that do not map to a known category.
|
|
final class UnknownBackendException extends BackendException {
|
|
const UnknownBackendException(
|
|
super.message, {
|
|
super.statusCode,
|
|
super.requestId,
|
|
super.backendCode,
|
|
});
|
|
}
|