diff --git a/packages/celest_core/CHANGELOG.md b/packages/celest_core/CHANGELOG.md index 1d3486b7..d073b734 100644 --- a/packages/celest_core/CHANGELOG.md +++ b/packages/celest_core/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.4.1 + +- chore(core): Deserialize errors returned from backend + ## 0.4.0 This release introduces support for HTTP customization, improved ergonomics, and a preview of running Flutter and UI code in the sky! diff --git a/packages/celest_core/lib/src/base/base_protocol.dart b/packages/celest_core/lib/src/base/base_protocol.dart index 468b6d64..bb77a4bb 100644 --- a/packages/celest_core/lib/src/base/base_protocol.dart +++ b/packages/celest_core/lib/src/base/base_protocol.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'package:celest_core/celest_core.dart'; import 'package:celest_core/src/base/celest_base.dart'; import 'package:http/http.dart' as http; +import 'package:http_parser/http_parser.dart'; mixin BaseProtocol { CelestBase get celest; @@ -40,15 +41,32 @@ mixin BaseProtocol { 'content-type': 'application/json', }, ); - if (resp.statusCode == 401) { - throw UnauthorizedException(); - } - if (resp.statusCode != 200) { - throw http.ClientException( - '${resp.statusCode}: ${resp.body}', - uri, - ); + return switch (resp.statusCode) { + 200 => jsonDecode(resp.body) as Map, + 400 => _error(resp, BadRequestException.new), + 401 => _error(resp, UnauthorizedException.new), + 500 => _error(resp, InternalServerError.new), + _ => throw http.ClientException( + '${resp.statusCode}: ${resp.body}', + uri, + ), + }; + } + + Never _error( + http.Response response, + T Function(String message) createError, + ) { + final mediaType = switch (response.headers['content-type']) { + final contentType? => MediaType.parse(contentType), + _ => throw createError(response.body), + }; + if (mediaType.mimeType != 'application/json') { + throw createError(response.body); } - return jsonDecode(resp.body) as Map; + final json = jsonDecode(response.body) as Map; + final error = json['error'] as Map?; + final message = error?['message'] as String?; + throw createError(message ?? response.body); } } diff --git a/packages/celest_core/pubspec.yaml b/packages/celest_core/pubspec.yaml index 1e774a15..2b73aaf3 100644 --- a/packages/celest_core/pubspec.yaml +++ b/packages/celest_core/pubspec.yaml @@ -15,6 +15,7 @@ dependencies: os_detect: ^2.0.1 path: ^1.9.0 native_storage: ^0.1.0 + http_parser: ^4.0.2 dev_dependencies: lints: ^4.0.0