Replace as Data cast in Service.dart with a method that throws a 400 on error

This commit is contained in:
Tobe O 2019-04-10 22:26:43 -04:00
parent 3802668cfc
commit 53b47dd43f
2 changed files with 34 additions and 12 deletions

View file

@ -6,6 +6,7 @@
* Allow setting of `bodyAsObject`, `bodyAsMap`, or `bodyAsList` **exactly once**.
* Resolve named singletons in `resolveInjection`.
* Fix a bug where `Service.parseId<double>` would attempt to parse an `int`.
* Replace as Data cast in Service.dart with a method that throws a 400 on error.
# 2.0.0-alpha.24
* Add `AngelEnv` class to `core`.

View file

@ -8,6 +8,7 @@ import '../util.dart';
import 'anonymous_service.dart';
import 'hooked_service.dart' show HookedService;
import 'metadata.dart';
import 'request_context.dart';
import 'response_context.dart';
import 'routable.dart';
import 'server.dart';
@ -72,6 +73,26 @@ class Service<Id, Data> extends Routable {
/// Closes this service, including any database connections or stream controllers.
void close() {}
/// An optional [readData] function can be passed to handle non-map/non-json bodies.
Service({FutureOr<Data> Function(RequestContext, ResponseContext) readData}) {
_readData = readData ??
(req, res) {
if (req.bodyAsObject is! Data) {
throw AngelHttpException.badRequest(
message:
'Invalid request body. Expected $Data; found ${req.bodyAsObject} instead.');
} else {
return req.bodyAsObject as Data;
}
};
}
FutureOr<Data> Function(RequestContext, ResponseContext) _readData;
/// A [Function] that reads the request body and converts it into [Data].
FutureOr<Data> Function(RequestContext, ResponseContext) get readData =>
_readData;
/// Retrieves the first object from the result of calling [index] with the given [params].
///
/// If the result of [index] is `null`, OR an empty [Iterable], a 404 `AngelHttpException` will be thrown.
@ -215,10 +236,10 @@ class Service<Id, Data> extends Routable {
Middleware createMiddleware =
getAnnotation<Middleware>(service.create, app.container.reflector);
post('/', (req, ResponseContext res) {
return req.parseBody().then((_) {
return this
return req.parseBody().then((_) async {
return await this
.create(
req.bodyAsMap as Data,
await readData(req, res),
mergeMap([
{'query': req.queryParameters},
restProvider,
@ -254,10 +275,10 @@ class Service<Id, Data> extends Routable {
Middleware modifyMiddleware =
getAnnotation<Middleware>(service.modify, app.container.reflector);
patch('/:id', (req, res) {
return req.parseBody().then((_) {
return this.modify(
return req.parseBody().then((_) async {
return await this.modify(
parseId<Id>(req.params['id']),
req.bodyAsMap as Data,
await readData(req, res),
mergeMap([
{'query': req.queryParameters},
restProvider,
@ -273,10 +294,10 @@ class Service<Id, Data> extends Routable {
Middleware updateMiddleware =
getAnnotation<Middleware>(service.update, app.container.reflector);
post('/:id', (req, res) {
return req.parseBody().then((_) {
return this.update(
return req.parseBody().then((_) async {
return await this.update(
parseId<Id>(req.params['id']),
req.bodyAsMap as Data,
await readData(req, res),
mergeMap([
{'query': req.queryParameters},
restProvider,
@ -289,10 +310,10 @@ class Service<Id, Data> extends Routable {
..addAll(
(updateMiddleware == null) ? [] : updateMiddleware.handlers));
put('/:id', (req, res) {
return req.parseBody().then((_) {
return this.update(
return req.parseBody().then((_) async {
return await this.update(
parseId<Id>(req.params['id']),
req.bodyAsMap as Data,
await readData(req, res),
mergeMap([
{'query': req.queryParameters},
restProvider,