Better errors

This commit is contained in:
thosakwe 2017-01-14 10:39:11 -05:00
parent 4ad4180f22
commit 462c4f4a79
3 changed files with 80 additions and 76 deletions

View file

@ -1,6 +1,6 @@
# angel_framework # angel_framework
[![pub 1.0.0-dev.45](https://img.shields.io/badge/pub-1.0.0--dev.45-red.svg)](https://pub.dartlang.org/packages/angel_framework) [![pub 1.0.0-dev.46](https://img.shields.io/badge/pub-1.0.0--dev.46-red.svg)](https://pub.dartlang.org/packages/angel_framework)
[![build status](https://travis-ci.org/angel-dart/framework.svg)](https://travis-ci.org/angel-dart/framework) [![build status](https://travis-ci.org/angel-dart/framework.svg)](https://travis-ci.org/angel-dart/framework)
Core libraries for the Angel Framework. Core libraries for the Angel Framework.

View file

@ -190,98 +190,105 @@ class Angel extends AngelBase {
} }
Future handleRequest(HttpRequest request) async { Future handleRequest(HttpRequest request) async {
_beforeProcessed.add(request); try {
_beforeProcessed.add(request);
final req = await RequestContext.from(request, this); final req = await RequestContext.from(request, this);
final res = new ResponseContext(request.response, this); final res = new ResponseContext(request.response, this);
String requestedUrl = request.uri.path.replaceAll(_straySlashes, ''); String requestedUrl = request.uri.path.replaceAll(_straySlashes, '');
if (requestedUrl.isEmpty) requestedUrl = '/'; if (requestedUrl.isEmpty) requestedUrl = '/';
final resolved = final resolved =
resolveAll(requestedUrl, requestedUrl, method: request.method); resolveAll(requestedUrl, requestedUrl, method: request.method);
for (final result in resolved) req.params.addAll(result.allParams); for (final result in resolved) req.params.addAll(result.allParams);
if (resolved.isNotEmpty) { if (resolved.isNotEmpty) {
final route = resolved.first.route; final route = resolved.first.route;
req.inject(Match, route.match(requestedUrl)); req.inject(Match, route.match(requestedUrl));
} }
final m = new MiddlewarePipeline(resolved); final m = new MiddlewarePipeline(resolved);
req.inject(MiddlewarePipeline, m); req.inject(MiddlewarePipeline, m);
final pipeline = []..addAll(before)..addAll(m.handlers)..addAll(after); final pipeline = []..addAll(before)..addAll(m.handlers)..addAll(after);
_printDebug('Handler sequence on $requestedUrl: $pipeline'); _printDebug('Handler sequence on $requestedUrl: $pipeline');
for (final handler in pipeline) { for (final handler in pipeline) {
try { try {
_printDebug('Executing handler: $handler'); _printDebug('Executing handler: $handler');
final result = await executeHandler(handler, req, res); final result = await executeHandler(handler, req, res);
_printDebug('Result: $result'); _printDebug('Result: $result');
if (!result) { if (!result) {
_printDebug('Last executed handler: $handler'); _printDebug('Last executed handler: $handler');
break; break;
} else { } else {
_printDebug( _printDebug(
'Handler completed successfully, did not terminate response: $handler'); 'Handler completed successfully, did not terminate response: $handler');
} }
} catch (e, st) { } catch (e, st) {
_printDebug('Caught error in handler $handler: $e'); _printDebug('Caught error in handler $handler: $e');
_printDebug(st); _printDebug(st);
if (e is AngelHttpException) { if (e is AngelHttpException) {
// Special handling for AngelHttpExceptions :) // Special handling for AngelHttpExceptions :)
try { try {
res.statusCode = e.statusCode; res.statusCode = e.statusCode;
List<String> accept = List<String> accept =
request.headers[HttpHeaders.ACCEPT] ?? ['*/*']; request.headers[HttpHeaders.ACCEPT] ?? ['*/*'];
if (accept.isEmpty || if (accept.isEmpty ||
accept.contains('*/*') || accept.contains('*/*') ||
accept.contains(ContentType.JSON.mimeType) || accept.contains(ContentType.JSON.mimeType) ||
accept.contains("application/javascript")) { accept.contains("application/javascript")) {
res.serialize(e.toMap()); res.serialize(e.toMap());
} else { } else {
await _errorHandler(e, req, res); await _errorHandler(e, req, res);
}
// _finalizeResponse(request, res);
} catch (e, st) {
_fatalErrorStream.add(
new AngelFatalError(request: request, error: e, stack: st));
} }
// _finalizeResponse(request, res); } else {
} catch (e, st) {
_fatalErrorStream.add( _fatalErrorStream.add(
new AngelFatalError(request: request, error: e, stack: st)); new AngelFatalError(request: request, error: e, stack: st));
} }
} else {
_fatalErrorStream
.add(new AngelFatalError(request: request, error: e, stack: st));
}
break; break;
}
} }
}
try { try {
_afterProcessed.add(request); _afterProcessed.add(request);
if (!res.willCloseItself) { if (!res.willCloseItself) {
for (var finalizer in responseFinalizers) { for (var finalizer in responseFinalizers) {
await finalizer(req, res); await finalizer(req, res);
}
for (var key in res.headers.keys) {
request.response.headers.set(key, res.headers[key]);
}
request.response.headers.chunkedTransferEncoding =
res.chunked ?? true;
request.response
..statusCode = res.statusCode
..cookies.addAll(res.cookies)
..add(res.buffer.takeBytes());
await request.response.close();
} }
} catch (e, st) {
for (var key in res.headers.keys) { _fatalErrorStream
request.response.headers.set(key, res.headers[key]); .add(new AngelFatalError(request: request, error: e, stack: st));
}
request.response.headers.chunkedTransferEncoding = res.chunked ?? true;
request.response
..statusCode = res.statusCode
..cookies.addAll(res.cookies)
..add(res.buffer.takeBytes());
await request.response.close();
} }
} catch (e) { } catch (e, st) {
failSilently(request, res); _fatalErrorStream
.add(new AngelFatalError(request: request, error: e, stack: st));
} }
} }
@ -335,9 +342,6 @@ class Angel extends AngelBase {
_onController.add(controllers[configurer.findExpose().path] = configurer); _onController.add(controllers[configurer.findExpose().path] = configurer);
} }
/// Fallback when an error is thrown while handling a request.
void failSilently(HttpRequest request, ResponseContext res) {}
/// Starts the server, wrapped in a [runZoned] call. /// Starts the server, wrapped in a [runZoned] call.
void listen({InternetAddress address, int port: 3000}) { void listen({InternetAddress address, int port: 3000}) {
runZoned(() async { runZoned(() async {

View file

@ -1,5 +1,5 @@
name: angel_framework name: angel_framework
version: 1.0.0-dev.45 version: 1.0.0-dev.46
description: Core libraries for the Angel framework. description: Core libraries for the Angel framework.
author: Tobe O <thosakwe@gmail.com> author: Tobe O <thosakwe@gmail.com>
homepage: https://github.com/angel-dart/angel_framework homepage: https://github.com/angel-dart/angel_framework