Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(426)

Unified Diff: lib/shelf_io.dart

Issue 1417523005: Include the request context for shelf_io errors. (Closed) Base URL: git@github.com:dart-lang/shelf@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « CHANGELOG.md ('k') | pubspec.yaml » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/shelf_io.dart
diff --git a/lib/shelf_io.dart b/lib/shelf_io.dart
index 7d0c053d427cf8b690d1a2598c8b108ac2c1aa78..c2813c7c49df7934ee3801803397b0dde1ddef01 100644
--- a/lib/shelf_io.dart
+++ b/lib/shelf_io.dart
@@ -53,56 +53,60 @@ void serveRequests(Stream<HttpRequest> requests, Handler handler) {
catchTopLevelErrors(() {
requests.listen((request) => handleRequest(request, handler));
}, (error, stackTrace) {
- _logError('Asynchronous error\n$error', stackTrace);
+ _logTopLevelError('Asynchronous error\n$error', stackTrace);
});
}
/// Uses [handler] to handle [request].
///
/// Returns a [Future] which completes when the request has been handled.
-Future handleRequest(HttpRequest request, Handler handler) {
+Future handleRequest(HttpRequest request, Handler handler) async {
var shelfRequest;
try {
shelfRequest = _fromHttpRequest(request);
} catch (error, stackTrace) {
- var response = _logError('Error parsing request.\n$error', stackTrace);
- return _writeResponse(response, request.response);
+ var response = _logTopLevelError(
+ 'Error parsing request.\n$error', stackTrace);
+ await _writeResponse(response, request.response);
+ return;
}
// TODO(nweiz): abstract out hijack handling to make it easier to implement an
// adapter.
- return new Future.sync(() => handler(shelfRequest))
- .catchError((error, stackTrace) {
- if (error is HijackException) {
- // A HijackException should bypass the response-writing logic entirely.
- if (!shelfRequest.canHijack) throw error;
-
- // If the request wasn't hijacked, we shouldn't be seeing this exception.
- return _logError(
- "Caught HijackException, but the request wasn't hijacked.",
- stackTrace);
- }
-
- return _logError('Error thrown by handler.\n$error', stackTrace);
- }).then((response) {
- if (response == null) {
- return _writeResponse(
- _logError('null response from handler.'), request.response);
- } else if (shelfRequest.canHijack) {
- return _writeResponse(response, request.response);
- }
-
- var message = new StringBuffer()
- ..writeln("Got a response for hijacked request "
- "${shelfRequest.method} ${shelfRequest.requestedUri}:")
- ..writeln(response.statusCode);
- response.headers
- .forEach((key, value) => message.writeln("${key}: ${value}"));
- throw new Exception(message.toString().trim());
- }).catchError((error, stackTrace) {
- // Ignore HijackExceptions.
- if (error is! HijackException) throw error;
- });
+ var response;
+ try {
+ response = await handler(shelfRequest);
+ } on HijackException catch (error, stackTrace) {
+ // A HijackException should bypass the response-writing logic entirely.
+ if (!shelfRequest.canHijack) return;
+
+ // If the request wasn't hijacked, we shouldn't be seeing this exception.
+ response = _logError(
+ shelfRequest,
+ "Caught HijackException, but the request wasn't hijacked.",
+ stackTrace);
+ } catch (error, stackTrace) {
+ response = _logError(
+ shelfRequest, 'Error thrown by handler.\n$error', stackTrace);
+ }
+
+ if (response == null) {
+ await _writeResponse(
+ _logError(shelfRequest, 'null response from handler.'),
+ request.response);
+ return;
+ } else if (shelfRequest.canHijack) {
+ await _writeResponse(response, request.response);
+ return;
+ }
+
+ var message = new StringBuffer()
+ ..writeln("Got a response for hijacked request "
+ "${shelfRequest.method} ${shelfRequest.requestedUri}:")
+ ..writeln(response.statusCode);
+ response.headers
+ .forEach((key, value) => message.writeln("${key}: ${value}"));
+ throw new Exception(message.toString().trim());
}
/// Creates a new [Request] from the provided [HttpRequest].
@@ -154,7 +158,20 @@ Future _writeResponse(Response response, HttpResponse httpResponse) {
// TODO(kevmoo) A developer mode is needed to include error info in response
// TODO(kevmoo) Make error output plugable. stderr, logging, etc
-Response _logError(String message, [StackTrace stackTrace]) {
+Response _logError(Request request, String message, [StackTrace stackTrace]) {
+ // Add information about the request itself.
+ var buffer = new StringBuffer();
+ buffer.write("${request.method} ${request.requestedUri.path}");
+ if (request.requestedUri.query.isNotEmpty) {
+ buffer.write("?${request.requestedUri.query}");
+ }
+ buffer.writeln();
+ buffer.write(message);
+
+ return _logTopLevelError(buffer.toString(), stackTrace);
+}
+
+Response _logTopLevelError(String message, [StackTrace stackTrace]) {
var chain = new Chain.current();
if (stackTrace != null) {
chain = new Chain.forTrace(stackTrace);
« no previous file with comments | « CHANGELOG.md ('k') | pubspec.yaml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698