diff --git a/CHANGELOG.md b/CHANGELOG.md index f14f9a0..cbb514e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +## [0.4.7] - 2026-04-27 + +* Added `isMaintenanceError` getter on `ErrorResult?` extension - returns `true` + for `GlobalErrorCode.maintenanceError`. +* `isTemporaryServerError` now also returns `true` for maintenance errors - + maintenance is treated as a temporary server state. +* `HttpStatus.badGateway` (502) is no longer included in + `isTemporaryServerError`. It was a fallback for maintenance handling; with + an explicit `maintenanceError` code, 502 should be reported separately. + ## [0.4.6] - 2026-04-02 * Added `maintenanceError` and `serviceDownError` error codes to `GlobalErrorCode`. diff --git a/lib/src/error_result_extension.dart b/lib/src/error_result_extension.dart index 5a7749a..ad067eb 100644 --- a/lib/src/error_result_extension.dart +++ b/lib/src/error_result_extension.dart @@ -23,6 +23,12 @@ extension CommonErrorResultExtensionErrorCode on ErrorResult? { bool get isExternalServiceError => toError()?.isGlobalError(GlobalErrorCode.externalServiceError) ?? false; + /// Определяет, является ли ошибка сообщением о режиме обслуживания. + /// + /// См. [GlobalErrorCode.maintenanceError]. + bool get isMaintenanceError => + toError()?.isGlobalError(GlobalErrorCode.maintenanceError) ?? false; + /// Определяет, является ли текущий результат ошибкой сокет соединения. bool get isSocketConnectionFailed => toError()?.isNetworkError(NetworkErrorCode.socketConnectionFailed) ?? @@ -65,19 +71,22 @@ extension CommonErrorResultExtensionErrorCode on ErrorResult? { /// Расширения [ErrorResult] для работы с кодами общих ошибок. extension InternalErrorCodeExtensionErrorResult on ErrorResult { - static List get _temporaryServerStatuses => [ - HttpStatus.badGateway, + static const _temporaryServerStatuses = { HttpStatus.serviceUnavailable, HttpStatus.gatewayTimeout, - ]; + }; /// Определяет, является ли текущий результат ошибкой взаимодействия с внешними сервисами. bool get isEmptyDataError => isInternalError(InternalErrorCode.emptyData); /// Определяет, является ли текущий результат временной ошибкой сервера. + /// + /// Включает в себя режим обслуживания (см. [isMaintenanceError]) - он + /// также считается временным состоянием сервера. bool get isTemporaryServerError => - toError()?.isInternalError(InternalErrorCode.temporaryServerError) ?? - _temporaryServerStatuses.contains(toDioError()?.response?.statusCode); + isMaintenanceError || + (toError()?.isInternalError(InternalErrorCode.temporaryServerError) ?? + _temporaryServerStatuses.contains(toDioError()?.response?.statusCode)); /// Определяет, соответствует ли ошибка указанному коду [InternalErrorCode] если указан. bool isInternalError([int? code]) => diff --git a/pubspec.yaml b/pubspec.yaml index ef290a6..d99570a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: innim_remote_error description: Remote error object and common codes for Innim projects. Using Dio. -version: 0.4.6 +version: 0.4.7 homepage: https://github.com/innim/ repository: https://github.com/Innim/flutter_remote_error issue_tracker: https://github.com/Innim/flutter_remote_error/issues diff --git a/test/error_result_extension_test.dart b/test/error_result_extension_test.dart index c68f8e0..2995ecf 100644 --- a/test/error_result_extension_test.dart +++ b/test/error_result_extension_test.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:dio/dio.dart'; import 'package:innim_remote_error/innim_remote_error.dart'; import 'package:test/test.dart'; @@ -85,6 +87,47 @@ void main() { }); }); + group('isMaintenanceError', () { + test('should return true for GlobalErrorCode.maintenanceError', () { + final res = _remoteError( + GlobalErrorCode.domain, + GlobalErrorCode.maintenanceError, + ); + + expect(res.isMaintenanceError, isTrue); + }); + + test('should return false for other GlobalErrorCode code', () { + final res = _remoteError( + GlobalErrorCode.domain, + GlobalErrorCode.notFound, + ); + + expect(res.isMaintenanceError, isFalse); + }); + + test('should return false for non-matching domain', () { + final res = _remoteError( + 'other_domain', + GlobalErrorCode.maintenanceError, + ); + + expect(res.isMaintenanceError, isFalse); + }); + + test('should return false when no RemoteError', () { + final res = _dioError(statusCode: 500); + + expect(res.isMaintenanceError, isFalse); + }); + + test('should return false when called on null', () { + const ErrorResult? res = null; + + expect(res.isMaintenanceError, isFalse); + }); + }); + group('isSocketConnectionFailed', () { test('should return true for NetworkErrorCode.socketConnectionFailed', () { @@ -411,6 +454,58 @@ void main() { }); }); + group('InternalErrorCodeExtensionErrorResult', () { + group('isTemporaryServerError', () { + test('should return true for InternalErrorCode.temporaryServerError', () { + final res = _remoteError( + InternalErrorCode.domain, + InternalErrorCode.temporaryServerError, + ); + + expect(res.isTemporaryServerError, isTrue); + }); + + test('should return true for GlobalErrorCode.maintenanceError', () { + final res = _remoteError( + GlobalErrorCode.domain, + GlobalErrorCode.maintenanceError, + ); + + expect(res.isTemporaryServerError, isTrue); + }); + + test('should return true if http status is 503', () { + final res = _dioError(statusCode: HttpStatus.serviceUnavailable); + + expect(res.isTemporaryServerError, isTrue); + }); + + test('should return true if http status is 504', () { + final res = _dioError(statusCode: HttpStatus.gatewayTimeout); + + expect(res.isTemporaryServerError, isTrue); + }); + + test('should return false if http status is 502', () { + final res = _dioError(statusCode: HttpStatus.badGateway); + + expect(res.isTemporaryServerError, isFalse); + }); + + test('should return false if http status is 500', () { + final res = _dioError(statusCode: HttpStatus.internalServerError); + + expect(res.isTemporaryServerError, isFalse); + }); + + test('should return false for other RemoteError', () { + final res = _remoteError('other', 1); + + expect(res.isTemporaryServerError, isFalse); + }); + }); + }); + group('toError()', () { test('should return RemoteError when error is RemoteError', () { const remoteError = RemoteError('test_domain', 123);