diff --git a/dwds/CHANGELOG.md b/dwds/CHANGELOG.md index a81c3ffb3..9447f173b 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 ac7f1a7a5..900bf8929 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 18eaff8aa..b6aa03a8b 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 @@ class ExtensionBackend { 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 b15c7b0f1..3b06d6e2c 100644 --- a/dwds/lib/src/services/debug_service.dart +++ b/dwds/lib/src/services/debug_service.dart @@ -11,10 +11,10 @@ import 'dart:math'; 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 @@ import 'chrome_proxy_service.dart'; bool _acceptNewConnections = true; int _clientsConnected = 0; +Logger _logger = Logger('DebugService'); + void Function(WebSocketChannel, String) _createNewConnectionHandler( ChromeProxyService chromeProxyService, ServiceExtensionRegistry serviceExtensionRegistry, { @@ -253,7 +255,9 @@ class DebugService { }; } 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 a5e281371..613b64a6f 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 @@ Future startHttpServer(String hostname, {int port}) async { 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 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 92818721c..9749f8bbe 100644 --- a/dwds/pubspec.yaml +++ b/dwds/pubspec.yaml @@ -30,6 +30,7 @@ dependencies: 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 49124b71c..6b6dedd4b 100644 --- a/dwds/test/expression_compiler_service_test.dart +++ b/dwds/test/expression_compiler_service_test.dart @@ -10,13 +10,15 @@ import 'dart:io'; 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 @@ void main() async { 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 c65022b27..212c732ec 100644 --- a/dwds/test/fixtures/server.dart +++ b/dwds/test/fixtures/server.dart @@ -10,10 +10,10 @@ import 'package:build_daemon/data/build_status.dart' as daemon; 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 @@ class TestServer { 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 09a08d221..408c447be 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 e3a6d3f06..5db5bdec4 100644 --- a/webdev/lib/src/serve/webdev_server.dart +++ b/webdev/lib/src/serve/webdev_server.dart @@ -14,14 +14,17 @@ import 'package:dwds/dwds.dart'; 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 @@ class WebDevServer { 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 14aadb1a7..ea5de9a3b 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 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 1c3d91612..687a60b59 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 2a516b0da..b57529d0a 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 @@ dependencies: 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'