Potential partial fix for broken socket exceptions (#1417)
* Handle http request serving errors
* Update changelogs, versions, build
* Addressed CR comments
* Addressed CR comments
diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md
index a81c3ff..9447f17 100644
--- a/dwds/CHANGELOG.md
+++ b/dwds/CHANGELOG.md
@@ -1,6 +1,7 @@
## 11.4.0
- Fix duplicated scripts returned by `VmService.getScripts` API.
+- Handle and log http request serving errors.
- Encode extension url asynchronously.
- Use default constant port for debug service.
- If we fail binding to the port, fall back to previous strategy
diff --git a/dwds/lib/src/injected/client.js b/dwds/lib/src/injected/client.js
index ac7f1a7..900bf89 100644
--- a/dwds/lib/src/injected/client.js
+++ b/dwds/lib/src/injected/client.js
@@ -1,4 +1,4 @@
-// Generated by dart2js (NullSafetyMode.unsound, no-legacy-javascript, new-holders), the Dart to JavaScript compiler version: 2.15.0-139.0.dev.
+// Generated by dart2js (NullSafetyMode.unsound, no-legacy-javascript, new-holders), the Dart to JavaScript compiler version: 2.15.0-150.0.dev.
// The code supports the following hooks:
// dartPrint(message):
// if this function is defined it is called instead of the Dart [print]
@@ -264,6 +264,18 @@
return letter - 87;
return -1;
},
+ SystemHash_combine(hash, value) {
+ if (typeof hash !== "number")
+ return hash.$add();
+ hash = hash + value & 536870911;
+ hash = hash + ((hash & 524287) << 10) & 536870911;
+ return hash ^ hash >>> 6;
+ },
+ SystemHash_finish(hash) {
+ hash = hash + ((hash & 67108863) << 3) & 536870911;
+ hash ^= hash >>> 11;
+ return hash + ((hash & 16383) << 15) & 536870911;
+ },
checkNotNullable(value, $name, $T) {
if (value == null)
throw A.wrapException(new A.NotNullableError($name, $T._eval$1("NotNullableError<0>")));
@@ -608,6 +620,8 @@
},
nullFuture_closure: function nullFuture_closure() {
},
+ SentinelValue: function SentinelValue() {
+ },
NotNullableError: function NotNullableError(t0, t1) {
this._name = t0;
this.$ti = t1;
@@ -3928,7 +3942,7 @@
return A._TimerImpl$periodic(milliseconds < 0 ? 0 : milliseconds, callback);
},
_rootPrint($self, $parent, zone, line) {
- A.printString(A._asStringS(line));
+ A.printString(A.S(A._asStringS(line)));
},
_printToZone(line) {
$.Zone__current.print$1(0, line);
@@ -5542,12 +5556,33 @@
Map_castFrom(source, $K, $V, K2, V2) {
return new A.CastMap(source, $K._eval$1("@<0>")._bind$1($V)._bind$1(K2)._bind$1(V2)._eval$1("CastMap<1,2,3,4>"));
},
+ Object_hash(object1, object2, object3, object4) {
+ var t1;
+ if (B.C_SentinelValue === object3) {
+ t1 = J.get$hashCode$(object1);
+ object2 = J.get$hashCode$(object2);
+ return A.SystemHash_finish(A.SystemHash_combine(A.SystemHash_combine($.$get$_hashSeed(), t1), object2));
+ }
+ if (B.C_SentinelValue === object4) {
+ t1 = J.get$hashCode$(object1);
+ object2 = J.get$hashCode$(object2);
+ object3 = J.get$hashCode$(object3);
+ return A.SystemHash_finish(A.SystemHash_combine(A.SystemHash_combine(A.SystemHash_combine($.$get$_hashSeed(), t1), object2), object3));
+ }
+ t1 = J.get$hashCode$(object1);
+ object2 = J.get$hashCode$(object2);
+ object3 = J.get$hashCode$(object3);
+ object4 = J.get$hashCode$(object4);
+ object4 = A.SystemHash_finish(A.SystemHash_combine(A.SystemHash_combine(A.SystemHash_combine(A.SystemHash_combine($.$get$_hashSeed(), t1), object2), object3), object4));
+ return object4;
+ },
print(object) {
- var toZone = $.printToZone;
+ var line = A.checkNotNullable(object, "object.toString()", type$.String),
+ toZone = $.printToZone;
if (toZone == null)
- A.printString(object);
+ A.printString(A.S(line));
else
- toZone.call$1(object);
+ toZone.call$1(line);
},
Uri_parse(uri) {
var delta, indices, schemeEnd, hostStart, portStart, pathStart, queryStart, fragmentStart, isSimple, scheme, t1, t2, schemeAuth, queryStart0, pathStart0, userInfoStart, userInfo, host, portNumber, port, path, query, _null = null,
@@ -6815,17 +6850,6 @@
WebSocket_WebSocket(url, protocols) {
return new WebSocket(url);
},
- _JenkinsSmiHash_combine(hash, value) {
- hash = hash + value & 536870911;
- hash = hash + ((hash & 524287) << 10) & 536870911;
- return hash ^ hash >>> 6;
- },
- _JenkinsSmiHash_hash4(a, b, c, d) {
- var t1 = A._JenkinsSmiHash_combine(A._JenkinsSmiHash_combine(A._JenkinsSmiHash_combine(A._JenkinsSmiHash_combine(0, a), b), c), d),
- hash = t1 + ((t1 & 67108863) << 3) & 536870911;
- hash ^= hash >>> 11;
- return hash + ((hash & 16383) << 15) & 536870911;
- },
_EventStreamSubscription$(_target, _eventType, onData, _useCapture, $T) {
var t1 = onData == null ? null : A._wrapZone(new A._EventStreamSubscription_closure(onData), type$.Event);
t1 = new A._EventStreamSubscription(_target, _eventType, t1, false, $T._eval$1("_EventStreamSubscription<0>"));
@@ -10027,9 +10051,10 @@
},
$signature: 24
};
+ A.SentinelValue.prototype = {};
A.NotNullableError.prototype = {
toString$0(_) {
- return "Null is not a valid value for the parameter '" + this._name + "' of type '" + A.createRuntimeType(this.$ti._precomputed1).toString$0(0) + "'";
+ return "Null is not a valid value for '" + this._name + "' of type '" + A.createRuntimeType(this.$ti._precomputed1).toString$0(0) + "'";
},
$isTypeError: 1
};
@@ -13145,7 +13170,7 @@
return A.Timer__createTimer(duration, type$.void_Function._as(f));
},
print$1(_, line) {
- A.printString(line);
+ A.printString(A.S(line));
}
};
A._RootZone_bindCallback_closure.prototype = {
@@ -16535,10 +16560,9 @@
var t2,
t1 = receiver.left;
t1.toString;
- t1 = B.JSNumber_methods.get$hashCode(t1);
t2 = receiver.top;
t2.toString;
- return A._JenkinsSmiHash_hash4(t1, B.JSNumber_methods.get$hashCode(t2), J.get$hashCode$(this.get$width(receiver)), J.get$hashCode$(this.get$height(receiver)));
+ return A.Object_hash(t1, t2, this.get$width(receiver), this.get$height(receiver));
},
get$_height(receiver) {
return receiver.height;
@@ -17541,16 +17565,13 @@
var t2, t3, t4,
t1 = receiver.left;
t1.toString;
- t1 = B.JSNumber_methods.get$hashCode(t1);
t2 = receiver.top;
t2.toString;
- t2 = B.JSNumber_methods.get$hashCode(t2);
t3 = receiver.width;
t3.toString;
- t3 = B.JSNumber_methods.get$hashCode(t3);
t4 = receiver.height;
t4.toString;
- return A._JenkinsSmiHash_hash4(t1, t2, t3, B.JSNumber_methods.get$hashCode(t4));
+ return A.Object_hash(t1, t2, t3, t4);
},
get$_height(receiver) {
return receiver.height;
@@ -24405,7 +24426,7 @@
_inherit = hunkHelpers.inherit,
_inheritMany = hunkHelpers.inheritMany;
_inherit(A.Object, null);
- _inheritMany(A.Object, [A.JS_CONST, J.Interceptor, J.ArrayIterator, A.Iterable, A.CastIterator, A.Closure, A.MapMixin, A.Error, A.ListIterator, A.Iterator, A.EmptyIterator, A.FixedLengthListMixin, A.UnmodifiableListMixin, A._ListBase_Object_ListMixin, A.Symbol, A.MapView, A.ConstantMap, A.JSInvocationMirror, A.TypeErrorDecoder, A.NullThrownFromJavaScriptException, A.ExceptionAndStackTrace, A._StackTrace, A._Required, A.LinkedHashMapCell, A.LinkedHashMapKeyIterator, A.JSSyntaxRegExp, A._MatchImplementation, A._AllMatchesIterator, A.StringMatch, A._StringAllMatchesIterator, A._Cell, A.Rti, A._FunctionParameters, A._Type, A._TimerImpl, A._AsyncAwaitCompleter, A.AsyncError, A._Completer, A._FutureListener, A._Future, A._AsyncCallbackEntry, A.Stream, A.StreamSubscription, A.StreamTransformerBase, A._StreamController, A._SyncStreamControllerDispatch, A._AsyncStreamControllerDispatch, A._BufferingStreamSubscription, A._StreamSinkWrapper, A._DelayedEvent, A._DelayedDone, A._PendingEvents, A._StreamIterator, A._ZoneFunction, A._RunNullaryZoneFunction, A._RunUnaryZoneFunction, A._RunBinaryZoneFunction, A._RegisterNullaryZoneFunction, A._RegisterUnaryZoneFunction, A._RegisterBinaryZoneFunction, A._ZoneSpecification, A._ZoneDelegate, A._Zone, A._HashMapKeyIterator, A.__SetBase_Object_SetMixin, A._HashSetIterator, A._LinkedHashSetCell, A._LinkedHashSetIterator, A.IterableMixin, A.ListMixin, A._UnmodifiableMapMixin, A._ListQueueIterator, A.SetMixin, A._SplayTreeNode, A._SplayTree, A._SplayTreeIterator, A.Codec, A._JsonStringifier, A._Utf8Encoder, A._BigIntImpl, A.DateTime, A.Duration, A.OutOfMemoryError, A.StackOverflowError, A._Exception, A.FormatException, A.IntegerDivisionByZeroException, A.Null, A._StringStackTrace, A.StringBuffer, A._Uri, A.UriData, A._SimpleUri, A.CssStyleDeclarationBase, A.EventStreamProvider, A._Html5NodeValidator, A.ImmutableListMixin, A.NodeValidatorBuilder, A._SimpleNodeValidator, A._SvgNodeValidator, A.FixedSizeListIterator, A._DOMWindowCrossFrame, A._SameOriginUriPolicy, A._ValidatingTreeSanitizer, A._StructuredClone, A._AcceptStructuredClone, A.JsObject, A.NullRejectionException, A._JSRandom, A._Random, A.AsyncMemoizer, A.DelegatingStreamSink, A.CopyOnWriteList, A.BuiltList, A.ListBuilder, A.BuiltListMultimap, A.ListMultimapBuilder, A.BuiltMap, A.MapBuilder, A.BuiltSet, A.SetBuilder, A.BuiltSetMultimap, A.SetMultimapBuilder, A.EnumClass, A.IndentingBuiltValueToStringHelper, A.JsonObject, A.FullType, A.BigIntSerializer, A.BoolSerializer, A.BuiltJsonSerializers, A.BuiltJsonSerializersBuilder, A.BuiltListMultimapSerializer, A.BuiltListSerializer, A.BuiltMapSerializer, A.BuiltSetMultimapSerializer, A.BuiltSetSerializer, A.DateTimeSerializer, A.DoubleSerializer, A.DurationSerializer, A.Int64Serializer, A.IntSerializer, A.JsonObjectSerializer, A.NullSerializer, A.NumSerializer, A.RegExpSerializer, A.StringSerializer, A.UriSerializer, A.DefaultEquality, A.IterableEquality, A.ListEquality, A._UnorderedEquality, A._MapEntry, A.MapEquality, A.DeepCollectionEquality, A.BuildResult, A._$BuildStatusSerializer, A._$BuildResultSerializer, A.BuildResultBuilder, A.ConnectRequest, A._$ConnectRequestSerializer, A.ConnectRequestBuilder, A.DebugEvent, A._$DebugEventSerializer, A.DebugEventBuilder, A.DevToolsRequest, A.DevToolsResponse, A._$DevToolsRequestSerializer, A._$DevToolsResponseSerializer, A.DevToolsRequestBuilder, A.DevToolsResponseBuilder, A.ErrorResponse, A._$ErrorResponseSerializer, A.ErrorResponseBuilder, A.ExtensionRequest, A.ExtensionResponse, A.ExtensionEvent, A.BatchedEvents, A._$ExtensionRequestSerializer, A._$ExtensionResponseSerializer, A._$ExtensionEventSerializer, A._$BatchedEventsSerializer, A.ExtensionRequestBuilder, A.ExtensionResponseBuilder, A.ExtensionEventBuilder, A.BatchedEventsBuilder, A.IsolateExit, A.IsolateStart, A._$IsolateExitSerializer, A._$IsolateStartSerializer, A.IsolateExitBuilder, A.IsolateStartBuilder, A.RegisterEvent, A._$RegisterEventSerializer, A.RegisterEventBuilder, A.RunRequest, A._$RunRequestSerializer, A.SocketClient, A.Int64, A.Level, A.LogRecord, A.Logger, A.Pool, A.PoolResource, A.StreamChannelMixin, A._GuaranteeSink, A.StreamChannelController, A.Uuid, A.WebSocketChannelException, A.LegacyRestarter, A.ReloadingManager, A.HotReloadFailedException, A.RequireRestarter]);
+ _inheritMany(A.Object, [A.JS_CONST, J.Interceptor, J.ArrayIterator, A.Iterable, A.CastIterator, A.Closure, A.MapMixin, A.Error, A.SentinelValue, A.ListIterator, A.Iterator, A.EmptyIterator, A.FixedLengthListMixin, A.UnmodifiableListMixin, A._ListBase_Object_ListMixin, A.Symbol, A.MapView, A.ConstantMap, A.JSInvocationMirror, A.TypeErrorDecoder, A.NullThrownFromJavaScriptException, A.ExceptionAndStackTrace, A._StackTrace, A._Required, A.LinkedHashMapCell, A.LinkedHashMapKeyIterator, A.JSSyntaxRegExp, A._MatchImplementation, A._AllMatchesIterator, A.StringMatch, A._StringAllMatchesIterator, A._Cell, A.Rti, A._FunctionParameters, A._Type, A._TimerImpl, A._AsyncAwaitCompleter, A.AsyncError, A._Completer, A._FutureListener, A._Future, A._AsyncCallbackEntry, A.Stream, A.StreamSubscription, A.StreamTransformerBase, A._StreamController, A._SyncStreamControllerDispatch, A._AsyncStreamControllerDispatch, A._BufferingStreamSubscription, A._StreamSinkWrapper, A._DelayedEvent, A._DelayedDone, A._PendingEvents, A._StreamIterator, A._ZoneFunction, A._RunNullaryZoneFunction, A._RunUnaryZoneFunction, A._RunBinaryZoneFunction, A._RegisterNullaryZoneFunction, A._RegisterUnaryZoneFunction, A._RegisterBinaryZoneFunction, A._ZoneSpecification, A._ZoneDelegate, A._Zone, A._HashMapKeyIterator, A.__SetBase_Object_SetMixin, A._HashSetIterator, A._LinkedHashSetCell, A._LinkedHashSetIterator, A.IterableMixin, A.ListMixin, A._UnmodifiableMapMixin, A._ListQueueIterator, A.SetMixin, A._SplayTreeNode, A._SplayTree, A._SplayTreeIterator, A.Codec, A._JsonStringifier, A._Utf8Encoder, A._BigIntImpl, A.DateTime, A.Duration, A.OutOfMemoryError, A.StackOverflowError, A._Exception, A.FormatException, A.IntegerDivisionByZeroException, A.Null, A._StringStackTrace, A.StringBuffer, A._Uri, A.UriData, A._SimpleUri, A.CssStyleDeclarationBase, A.EventStreamProvider, A._Html5NodeValidator, A.ImmutableListMixin, A.NodeValidatorBuilder, A._SimpleNodeValidator, A._SvgNodeValidator, A.FixedSizeListIterator, A._DOMWindowCrossFrame, A._SameOriginUriPolicy, A._ValidatingTreeSanitizer, A._StructuredClone, A._AcceptStructuredClone, A.JsObject, A.NullRejectionException, A._JSRandom, A._Random, A.AsyncMemoizer, A.DelegatingStreamSink, A.CopyOnWriteList, A.BuiltList, A.ListBuilder, A.BuiltListMultimap, A.ListMultimapBuilder, A.BuiltMap, A.MapBuilder, A.BuiltSet, A.SetBuilder, A.BuiltSetMultimap, A.SetMultimapBuilder, A.EnumClass, A.IndentingBuiltValueToStringHelper, A.JsonObject, A.FullType, A.BigIntSerializer, A.BoolSerializer, A.BuiltJsonSerializers, A.BuiltJsonSerializersBuilder, A.BuiltListMultimapSerializer, A.BuiltListSerializer, A.BuiltMapSerializer, A.BuiltSetMultimapSerializer, A.BuiltSetSerializer, A.DateTimeSerializer, A.DoubleSerializer, A.DurationSerializer, A.Int64Serializer, A.IntSerializer, A.JsonObjectSerializer, A.NullSerializer, A.NumSerializer, A.RegExpSerializer, A.StringSerializer, A.UriSerializer, A.DefaultEquality, A.IterableEquality, A.ListEquality, A._UnorderedEquality, A._MapEntry, A.MapEquality, A.DeepCollectionEquality, A.BuildResult, A._$BuildStatusSerializer, A._$BuildResultSerializer, A.BuildResultBuilder, A.ConnectRequest, A._$ConnectRequestSerializer, A.ConnectRequestBuilder, A.DebugEvent, A._$DebugEventSerializer, A.DebugEventBuilder, A.DevToolsRequest, A.DevToolsResponse, A._$DevToolsRequestSerializer, A._$DevToolsResponseSerializer, A.DevToolsRequestBuilder, A.DevToolsResponseBuilder, A.ErrorResponse, A._$ErrorResponseSerializer, A.ErrorResponseBuilder, A.ExtensionRequest, A.ExtensionResponse, A.ExtensionEvent, A.BatchedEvents, A._$ExtensionRequestSerializer, A._$ExtensionResponseSerializer, A._$ExtensionEventSerializer, A._$BatchedEventsSerializer, A.ExtensionRequestBuilder, A.ExtensionResponseBuilder, A.ExtensionEventBuilder, A.BatchedEventsBuilder, A.IsolateExit, A.IsolateStart, A._$IsolateExitSerializer, A._$IsolateStartSerializer, A.IsolateExitBuilder, A.IsolateStartBuilder, A.RegisterEvent, A._$RegisterEventSerializer, A.RegisterEventBuilder, A.RunRequest, A._$RunRequestSerializer, A.SocketClient, A.Int64, A.Level, A.LogRecord, A.Logger, A.Pool, A.PoolResource, A.StreamChannelMixin, A._GuaranteeSink, A.StreamChannelController, A.Uuid, A.WebSocketChannelException, A.LegacyRestarter, A.ReloadingManager, A.HotReloadFailedException, A.RequireRestarter]);
_inheritMany(J.Interceptor, [J.JSBool, J.JSNull, J.JavaScriptObject, J.JSArray, J.JSNumber, J.JSString, A.NativeByteBuffer, A.NativeTypedData, A.EventTarget, A.AccessibleNodeList, A.Blob, A.Event, A.CssTransformComponent, A.CssRule, A._CssStyleDeclaration_Interceptor_CssStyleDeclarationBase, A.CssStyleValue, A.DataTransferItemList, A.DomException, A.DomImplementation, A._DomRectList_Interceptor_ListMixin, A.DomRectReadOnly, A._DomStringList_Interceptor_ListMixin, A.DomTokenList, A._FileList_Interceptor_ListMixin, A.Gamepad, A.History, A._HtmlCollection_Interceptor_ListMixin, A.ImageData, A.Location, A.MediaList, A._MidiInputMap_Interceptor_MapMixin, A._MidiOutputMap_Interceptor_MapMixin, A.MimeType, A._MimeTypeArray_Interceptor_ListMixin, A._NodeList_Interceptor_ListMixin, A.Plugin, A._PluginArray_Interceptor_ListMixin, A._RtcStatsReport_Interceptor_MapMixin, A.SpeechGrammar, A._SpeechGrammarList_Interceptor_ListMixin, A.SpeechRecognitionResult, A._Storage_Interceptor_MapMixin, A.StyleSheet, A._TextTrackCueList_Interceptor_ListMixin, A.TimeRanges, A.Touch, A._TouchList_Interceptor_ListMixin, A.TrackDefaultList, A.Url, A.__CssRuleList_Interceptor_ListMixin, A.__GamepadList_Interceptor_ListMixin, A.__NamedNodeMap_Interceptor_ListMixin, A.__SpeechRecognitionResultList_Interceptor_ListMixin, A.__StyleSheetList_Interceptor_ListMixin, A.KeyRange, A.Length, A._LengthList_Interceptor_ListMixin, A.Number, A._NumberList_Interceptor_ListMixin, A.PointList, A._StringList_Interceptor_ListMixin, A.Transform, A._TransformList_Interceptor_ListMixin, A.AudioBuffer, A._AudioParamMap_Interceptor_MapMixin, A._SqlResultSetRowList_Interceptor_ListMixin]);
_inheritMany(J.JavaScriptObject, [J.PlainJavaScriptObject, J.UnknownJavaScriptObject, J.JavaScriptFunction, A.Promise, A.RequireLoader, A.JsError, A.JsMap]);
_inherit(J.JSUnmodifiableArray, J.JSArray);
@@ -25048,6 +25069,7 @@
;
B.C_JsonCodec = new A.JsonCodec();
B.C_OutOfMemoryError = new A.OutOfMemoryError();
+ B.C_SentinelValue = new A.SentinelValue();
B.C_Utf8Codec = new A.Utf8Codec();
B.C_Utf8Encoder = new A.Utf8Encoder();
B.C_Uuid = new A.Uuid();
@@ -25341,6 +25363,9 @@
_lazy($, "_BigIntImpl__parseRE", "$get$_BigIntImpl__parseRE", function() {
return A.RegExp_RegExp("^\\s*([+-]?)((0x[a-f0-9]+)|(\\d+)|([a-z0-9]+))\\s*$", false, false);
});
+ _lazyFinal($, "_hashSeed", "$get$_hashSeed", function() {
+ return A.objectHashCode(B.Type_Object_xQ6);
+ });
_lazyFinal($, "_scannerTables", "$get$_scannerTables", function() {
return A._createTables();
});
diff --git a/dwds/lib/src/servers/extension_backend.dart b/dwds/lib/src/servers/extension_backend.dart
index 18eaff8..b6aa03a 100644
--- a/dwds/lib/src/servers/extension_backend.dart
+++ b/dwds/lib/src/servers/extension_backend.dart
@@ -4,20 +4,25 @@
// @dart = 2.9
+import 'dart:async';
import 'dart:io';
import 'package:async/async.dart';
+
import 'package:http_multi_server/http_multi_server.dart';
+import 'package:logging/logging.dart';
import 'package:shelf/shelf.dart';
-import 'package:shelf/shelf_io.dart';
import '../../data/extension_request.dart';
import '../handlers/socket_connections.dart';
+import '../utilities/shared.dart';
import 'extension_debugger.dart';
const authenticationResponse = 'Dart Debug Authentication Success!\n\n'
'You can close this tab and launch the Dart Debug Extension again.';
+Logger _logger = Logger('ExtensiobBackend');
+
/// A backend for the Dart Debug Extension.
///
/// Sets up an SSE handler to communicate with the extension background.
@@ -50,7 +55,9 @@
return Response.notFound('');
}).add(_socketHandler.handler);
var server = await HttpMultiServer.bind(hostname, 0);
- serveRequests(server, cascade.handler);
+ serveHttpRequests(server, cascade.handler, (e, s) {
+ _logger.warning('Error serving requests', e, s);
+ });
return ExtensionBackend._(
_socketHandler, server.address.host, server.port, server);
}
diff --git a/dwds/lib/src/services/debug_service.dart b/dwds/lib/src/services/debug_service.dart
index b15c7b0..3b06d6e 100644
--- a/dwds/lib/src/services/debug_service.dart
+++ b/dwds/lib/src/services/debug_service.dart
@@ -11,10 +11,10 @@
import 'dart:typed_data';
import 'package:dds/dds.dart';
+import 'package:logging/logging.dart';
import 'package:pedantic/pedantic.dart';
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf.dart' hide Response;
-import 'package:shelf/shelf_io.dart';
import 'package:shelf_web_socket/shelf_web_socket.dart';
import 'package:sse/server/sse_handler.dart';
import 'package:vm_service/vm_service.dart';
@@ -29,6 +29,8 @@
bool _acceptNewConnections = true;
int _clientsConnected = 0;
+Logger _logger = Logger('DebugService');
+
void Function(WebSocketChannel, String) _createNewConnectionHandler(
ChromeProxyService chromeProxyService,
ServiceExtensionRegistry serviceExtensionRegistry, {
@@ -253,7 +255,9 @@
};
}
var server = await startHttpServer(hostname, port: 44456);
- serveRequests(server, handler);
+ serveHttpRequests(server, handler, (e, s) {
+ _logger.warning('Error serving requests', e, s);
+ });
return DebugService._(
chromeProxyService,
server.address.host,
diff --git a/dwds/lib/src/utilities/shared.dart b/dwds/lib/src/utilities/shared.dart
index a5e2813..613b64a 100644
--- a/dwds/lib/src/utilities/shared.dart
+++ b/dwds/lib/src/utilities/shared.dart
@@ -4,11 +4,16 @@
// @dart = 2.9
+import 'dart:async';
import 'dart:io';
import 'package:http_multi_server/http_multi_server.dart';
+import 'package:shelf/shelf.dart';
+import 'package:shelf/shelf_io.dart';
+import 'package:stack_trace/stack_trace.dart';
import 'package:vm_service/vm_service.dart';
-import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
+import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart'
+ as wip;
import '../../dwds.dart' show ChromeDebugException;
@@ -72,9 +77,20 @@
return httpServer;
}
-/// Throws an [ExceptionDetails] object if `exceptionDetails` is present on the
+/// Handles [requests] using [handler].
+///
+/// Captures all sync and async stack error traces and passes
+/// them to the [onError] handler.
+void serveHttpRequests(Stream<HttpRequest> requests, Handler handler,
+ void Function(Object, StackTrace) onError) {
+ return Chain.capture(() {
+ serveRequests(requests, handler);
+ }, onError: onError);
+}
+
+/// Throws an [wip.ExceptionDetails] object if `exceptionDetails` is present on the
/// result.
-void handleErrorIfPresent(WipResponse response,
+void handleErrorIfPresent(wip.WipResponse response,
{String evalContents, Object additionalDetails}) {
if (response == null) return;
if (response.result.containsKey('exceptionDetails')) {
diff --git a/dwds/pubspec.yaml b/dwds/pubspec.yaml
index 9281872..9749f8b 100644
--- a/dwds/pubspec.yaml
+++ b/dwds/pubspec.yaml
@@ -30,6 +30,7 @@
shelf_static: ^1.0.0
shelf_web_socket: ^1.0.0
source_maps: ^0.10.0
+ stack_trace: ^1.10.0
sse: ^4.1.0
# We pin the version because we implement the interface.
vm_service: 7.3.0
diff --git a/dwds/test/expression_compiler_service_test.dart b/dwds/test/expression_compiler_service_test.dart
index 49124b7..6b6dedd 100644
--- a/dwds/test/expression_compiler_service_test.dart
+++ b/dwds/test/expression_compiler_service_test.dart
@@ -10,13 +10,15 @@
import 'package:dwds/dwds.dart';
import 'package:dwds/src/utilities/shared.dart';
+import 'package:logging/logging.dart';
import 'package:path/path.dart' as p;
import 'package:shelf/shelf.dart';
-import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:test/test.dart';
import 'fixtures/logging.dart';
+Logger _logger = Logger('ExpressionCompilerServiceTest');
+
@TestOn('vm')
void main() async {
group('expression compiler service with fake asset server', () {
@@ -65,8 +67,11 @@
await service.initialize(moduleFormat: 'amd');
// setup asset server
- shelf_io.serveRequests(
- server, Cascade().add(service.handler).add(assetHandler).handler);
+ serveHttpRequests(
+ server, Cascade().add(service.handler).add(assetHandler).handler,
+ (e, s) {
+ _logger.warning('Error serving requests', e, s);
+ });
// generate full dill
File.fromUri(source)
diff --git a/dwds/test/fixtures/server.dart b/dwds/test/fixtures/server.dart
index c65022b..212c732 100644
--- a/dwds/test/fixtures/server.dart
+++ b/dwds/test/fixtures/server.dart
@@ -10,10 +10,10 @@
import 'package:devtools_server/devtools_server.dart' as devtools_lancher;
import 'package:dwds/data/build_result.dart';
import 'package:dwds/dwds.dart';
+import 'package:dwds/src/utilities/shared.dart';
import 'package:http_multi_server/http_multi_server.dart';
import 'package:logging/logging.dart';
import 'package:shelf/shelf.dart';
-import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
Logger _logger = Logger('TestServer');
@@ -127,12 +127,14 @@
cascade = cascade.add(ddcService.handler);
}
- shelf_io.serveRequests(
+ serveHttpRequests(
server,
pipeline
.addMiddleware(_logRequests)
.addMiddleware(dwds.middleware)
- .addHandler(cascade.handler));
+ .addHandler(cascade.handler), (e, s) {
+ _logger.warning('Error handling requests', e, s);
+ });
return TestServer._(
target,
diff --git a/webdev/CHANGELOG.md b/webdev/CHANGELOG.md
index 09a08d2..408c447 100644
--- a/webdev/CHANGELOG.md
+++ b/webdev/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 2.7.7-dev
+
+- Handle and log http request serving errors.
+
## 2.7.6
- Update SDK constraint to `>=2.14.0 <3.0.0`
diff --git a/webdev/lib/src/serve/webdev_server.dart b/webdev/lib/src/serve/webdev_server.dart
index e3a6d3f..5db5bde 100644
--- a/webdev/lib/src/serve/webdev_server.dart
+++ b/webdev/lib/src/serve/webdev_server.dart
@@ -14,14 +14,17 @@
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart';
import 'package:http_multi_server/http_multi_server.dart';
+import 'package:logging/logging.dart';
import 'package:shelf/shelf.dart';
-import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_proxy/shelf_proxy.dart';
import '../command/configuration.dart';
+import '../util.dart';
import 'chrome.dart';
import 'handlers/favicon_handler.dart';
+Logger _logger = Logger('WebDevServer');
+
class ServerOptions {
final Configuration configuration;
final int port;
@@ -179,7 +182,10 @@
server = await HttpMultiServer.bind(hostname, options.port);
}
- shelf_io.serveRequests(server, pipeline.addHandler(cascade.handler));
+ serveHttpRequests(server, pipeline.addHandler(cascade.handler), (e, s) {
+ _logger.warning('Error serving requests', e, s);
+ });
+
return WebDevServer._(
options.target,
server,
diff --git a/webdev/lib/src/util.dart b/webdev/lib/src/util.dart
index 14aadb1..ea5de9a 100644
--- a/webdev/lib/src/util.dart
+++ b/webdev/lib/src/util.dart
@@ -4,12 +4,27 @@
// @dart = 2.9
+import 'dart:async';
import 'dart:io';
import 'package:path/path.dart' as p;
+import 'package:shelf/shelf.dart';
+import 'package:shelf/shelf_io.dart';
+import 'package:stack_trace/stack_trace.dart';
const appName = 'webdev';
+/// Handles [requests] using [handler].
+///
+/// Captures all sync and async stack error traces and passes
+/// them to the [onError] handler.
+void serveHttpRequests(Stream<HttpRequest> requests, Handler handler,
+ void Function(Object, StackTrace) onError) {
+ return Chain.capture(() {
+ serveRequests(requests, handler);
+ }, onError: onError);
+}
+
/// The path to the root directory of the SDK.
final String _sdkDir = (() {
// The Dart executable is in "/path/to/sdk/bin/dart", so two levels up is
diff --git a/webdev/lib/src/version.dart b/webdev/lib/src/version.dart
index 1c3d916..687a60b 100644
--- a/webdev/lib/src/version.dart
+++ b/webdev/lib/src/version.dart
@@ -1,2 +1,2 @@
// Generated code. Do not modify.
-const packageVersion = '2.7.6';
+const packageVersion = '2.7.7-dev';
diff --git a/webdev/pubspec.yaml b/webdev/pubspec.yaml
index 2a516b0..b57529d 100644
--- a/webdev/pubspec.yaml
+++ b/webdev/pubspec.yaml
@@ -1,6 +1,6 @@
name: webdev
# Every time this changes you need to run `pub run build_runner build`.
-version: 2.7.6
+version: 2.7.7-dev
# We should not depend on a dev SDK before publishing.
# publish_to: none
homepage: https://github.com/dart-lang/webdev
@@ -32,6 +32,7 @@
shelf: ^1.0.0
shelf_proxy: ^1.0.0
shelf_static: ^1.0.0
+ stack_trace: ^1.10.0
sse: ^4.1.0
vm_service: '>=3.0.0 <8.0.0'
webkit_inspection_protocol: '>=0.4.0 <2.0.0'