Complete `onConnected` with error if connection fails to open (#42)
* Complete `onConnected` with error if connection fails to open
This prevents `onConnected` from hanging indefinitely if the `SseClient`
immediately fails to open.
Fixes https://github.com/dart-lang/sse/issues/41.
* Recompile the test app
* Add changelog entry and update version
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0ed01c9..4b921c2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 3.8.2
+
+- Complete `onConnected` with an error if the `SseClient` receives an error
+ before the connection is successfully opened.
+
## 3.8.1
- Fix an issue where closing the `SseConnection` stream would result in
diff --git a/lib/client/sse_client.dart b/lib/client/sse_client.dart
index 2958bed..00def10 100644
--- a/lib/client/sse_client.dart
+++ b/lib/client/sse_client.dart
@@ -57,6 +57,11 @@
_errorTimer = Timer(const Duration(seconds: 5), () {
_incomingController.addError(error);
close();
+ if (!_onConnected.isCompleted) {
+ // This call must happen after the call to close() which checks
+ // whether the completer was completed earlier.
+ _onConnected.completeError(error);
+ }
});
}
});
diff --git a/pubspec.yaml b/pubspec.yaml
index 9a44e4c..a99fd02 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
name: sse
-version: 3.8.1
+version: 3.8.2
homepage: https://github.com/dart-lang/sse
description: >-
Provides client and server functionality for setting up bi-directional
diff --git a/test/web/index.dart.js b/test/web/index.dart.js
index 614df07..5f962b9 100644
--- a/test/web/index.dart.js
+++ b/test/web/index.dart.js
@@ -1,4 +1,4 @@
-// Generated by dart2js (fast startup emitter, strong), the Dart to JavaScript compiler version: 2.12.0-223.0.dev.
+// Generated by dart2js (fast startup emitter, strong), the Dart to JavaScript compiler version: 2.12.0-133.2.beta.
// The code supports the following hooks:
// dartPrint(message):
// if this function is defined it is called instead of the Dart [print]
@@ -27,14 +27,6 @@
to[key] = from[key];
}
}
- function mixinProperties(from, to) {
- var keys = Object.keys(from);
- for (var i = 0; i < keys.length; i++) {
- var key = keys[i];
- if (!to.hasOwnProperty(key))
- to[key] = from[key];
- }
- }
var supportsDirectProtoAccess = function() {
var cls = function() {
};
@@ -66,7 +58,7 @@
for (var j = 0; j < keys.length; j++) {
var key = keys[j];
var f = holder[key];
- if (typeof f == "function")
+ if (typeof f == 'function')
f.name = key;
}
}
@@ -89,7 +81,7 @@
inherit(classes[i], sup);
}
function mixin(cls, mixin) {
- mixinProperties(mixin.prototype, cls.prototype);
+ copyProperties(mixin.prototype, cls.prototype);
cls.prototype.constructor = cls;
}
function lazyOld(holder, name, getterName, initializer) {
@@ -178,7 +170,7 @@
var funs = [];
for (var i = 0; i < funsOrNames.length; i++) {
var fun = funsOrNames[i];
- if (typeof fun == "string")
+ if (typeof fun == 'string')
fun = container[fun];
fun.$callName = callNames[i];
funs.push(fun);
@@ -267,7 +259,7 @@
LateError: function LateError(t0) {
this._message = t0;
},
- nullFuture_closure: function nullFuture_closure() {
+ closure: function closure() {
},
NotNullableError: function NotNullableError(t0, t1) {
this.__internal$_name = t0;
@@ -455,7 +447,7 @@
},
TypeErrorDecoder_extractPattern: function(message) {
var match, $arguments, argumentsExpr, expr, method, receiver;
- message = H.quoteStringForRegExp(message.replace(String({}), "$receiver$"));
+ message = H.quoteStringForRegExp(message.replace(String({}), '$receiver$'));
match = message.match(/\\\$[a-zA-Z]+\\\$/g);
if (match == null)
match = H.setRuntimeTypeInfo([], type$.JSArray_String);
@@ -464,11 +456,11 @@
expr = match.indexOf("\\$expr\\$");
method = match.indexOf("\\$method\\$");
receiver = match.indexOf("\\$receiver\\$");
- return new H.TypeErrorDecoder(message.replace(new RegExp("\\\\\\$arguments\\\\\\$", "g"), "((?:x|[^x])*)").replace(new RegExp("\\\\\\$argumentsExpr\\\\\\$", "g"), "((?:x|[^x])*)").replace(new RegExp("\\\\\\$expr\\\\\\$", "g"), "((?:x|[^x])*)").replace(new RegExp("\\\\\\$method\\\\\\$", "g"), "((?:x|[^x])*)").replace(new RegExp("\\\\\\$receiver\\\\\\$", "g"), "((?:x|[^x])*)"), $arguments, argumentsExpr, expr, method, receiver);
+ return new H.TypeErrorDecoder(message.replace(new RegExp('\\\\\\$arguments\\\\\\$', 'g'), '((?:x|[^x])*)').replace(new RegExp('\\\\\\$argumentsExpr\\\\\\$', 'g'), '((?:x|[^x])*)').replace(new RegExp('\\\\\\$expr\\\\\\$', 'g'), '((?:x|[^x])*)').replace(new RegExp('\\\\\\$method\\\\\\$', 'g'), '((?:x|[^x])*)').replace(new RegExp('\\\\\\$receiver\\\\\\$', 'g'), '((?:x|[^x])*)'), $arguments, argumentsExpr, expr, method, receiver);
},
TypeErrorDecoder_provokeCallErrorOn: function(expression) {
return function($expr$) {
- var $argumentsExpr$ = "$arguments$";
+ var $argumentsExpr$ = '$arguments$';
try {
$expr$.$method$($argumentsExpr$);
} catch (e) {
@@ -2898,6 +2890,22 @@
}($function, 1);
return $.Zone__current.registerBinaryCallback$3$1(new P._wrapJsFunctionForAsync_closure($protected), type$.void, type$.int, type$.dynamic);
},
+ Future_Future$value: function(value, $T) {
+ var t1 = new P._Future($.Zone__current, $T._eval$1("_Future<0>"));
+ t1._asyncComplete$1(value);
+ return t1;
+ },
+ _Future__chainForeignFuture: function(source, target) {
+ var e, s, exception;
+ target._state = 1;
+ try {
+ source.then$1$2$onError(new P._Future__chainForeignFuture_closure(target), new P._Future__chainForeignFuture_closure0(target), type$.Null);
+ } catch (exception) {
+ e = H.unwrapException(exception);
+ s = H.getTraceFromException(exception);
+ P.scheduleMicrotask(new P._Future__chainForeignFuture_closure1(target, e, s));
+ }
+ },
_Future__chainCoreFuture: function(source, target) {
var t1, t2, listeners;
for (t1 = type$._Future_dynamic; t2 = source._state, t2 === 2;)
@@ -2974,26 +2982,17 @@
$.Zone__current = oldZone;
t1 = _box_0.listenerValueOrError;
if (t4._is(t1)) {
- t5 = _box_0.listener.$ti;
- t5 = t5._eval$1("Future<2>")._is(t1) || !t5._rest[1]._is(t1);
- } else
- t5 = false;
- if (t5) {
- t4._as(t1);
result = _box_0.listener.result;
- if (t1 instanceof P._Future)
- if (t1._state >= 4) {
- current = t3._as(result._resultOrListeners);
- result._resultOrListeners = null;
- listeners = result._reverseListeners$1(current);
- result._state = t1._state;
- result._resultOrListeners = t1._resultOrListeners;
- _box_1.source = t1;
- continue;
- } else
- P._Future__chainCoreFuture(t1, result);
- else
- result._chainForeignFuture$1(t1);
+ if (t1._state >= 4) {
+ current = t3._as(result._resultOrListeners);
+ result._resultOrListeners = null;
+ listeners = result._reverseListeners$1(current);
+ result._state = t1._state;
+ result._resultOrListeners = t1._resultOrListeners;
+ _box_1.source = t1;
+ continue;
+ } else
+ P._Future__chainCoreFuture(t1, result);
return;
}
}
@@ -3023,7 +3022,7 @@
t1 = type$.dynamic_Function_Object;
if (t1._is(errorHandler))
return t1._as(errorHandler);
- throw H.wrapException(P.ArgumentError$value(errorHandler, "onError", "Error handler must accept one Object or one Object and a StackTrace as arguments, and return a valid result"));
+ throw H.wrapException(P.ArgumentError$value(errorHandler, "onError", "Error handler must accept one Object or one Object and a StackTrace as arguments, and return a a valid result"));
},
_microtaskLoop: function() {
var entry, next;
@@ -3263,13 +3262,13 @@
this.$this = t1;
},
_Future__chainForeignFuture_closure: function _Future__chainForeignFuture_closure(t0) {
- this.$this = t0;
+ this.target = t0;
},
_Future__chainForeignFuture_closure0: function _Future__chainForeignFuture_closure0(t0) {
- this.$this = t0;
+ this.target = t0;
},
_Future__chainForeignFuture_closure1: function _Future__chainForeignFuture_closure1(t0, t1, t2) {
- this.$this = t0;
+ this.target = t0;
this.e = t1;
this.s = t2;
},
@@ -4449,11 +4448,9 @@
return message != null ? "LateInitializationError: " + message : "LateInitializationError";
}
};
- H.nullFuture_closure.prototype = {
+ H.closure.prototype = {
call$0: function() {
- var t1 = new P._Future($.Zone__current, type$._Future_Null);
- t1._asyncComplete$1(null);
- return t1;
+ return P.Future_Future$value(null, type$.Null);
},
$signature: 14
};
@@ -5192,17 +5189,6 @@
}
return prev;
},
- _chainForeignFuture$1: function(source) {
- var e, s, exception, _this = this;
- _this._state = 1;
- try {
- source.then$1$2$onError(new P._Future__chainForeignFuture_closure(_this), new P._Future__chainForeignFuture_closure0(_this), type$.Null);
- } catch (exception) {
- e = H.unwrapException(exception);
- s = H.getTraceFromException(exception);
- P.scheduleMicrotask(new P._Future__chainForeignFuture_closure1(_this, e, s));
- }
- },
_complete$1: function(value) {
var listeners, _this = this,
t1 = _this.$ti;
@@ -5211,7 +5197,7 @@
if (t1._is(value))
P._Future__chainCoreFuture(value, _this);
else
- _this._chainForeignFuture$1(value);
+ P._Future__chainForeignFuture(value, _this);
else {
listeners = _this._removeListeners$0();
t1._precomputed1._as(value);
@@ -5264,7 +5250,7 @@
P._Future__chainCoreFuture(value, _this);
return;
}
- _this._chainForeignFuture$1(value);
+ P._Future__chainForeignFuture(value, _this);
},
_asyncCompleteError$2: function(error, stackTrace) {
type$.StackTrace._as(stackTrace);
@@ -5287,28 +5273,21 @@
};
P._Future__chainForeignFuture_closure.prototype = {
call$1: function(value) {
- var error, stackTrace, exception,
- t1 = this.$this;
+ var t1 = this.target;
t1._state = 0;
- try {
- t1._completeWithValue$1(t1.$ti._precomputed1._as(value));
- } catch (exception) {
- error = H.unwrapException(exception);
- stackTrace = H.getTraceFromException(exception);
- t1._completeError$2(error, stackTrace);
- }
+ t1._complete$1(value);
},
$signature: 5
};
P._Future__chainForeignFuture_closure0.prototype = {
call$2: function(error, stackTrace) {
- this.$this._completeError$2(error, type$.StackTrace._as(stackTrace));
+ this.target._completeError$2(error, type$.StackTrace._as(stackTrace));
},
$signature: 7
};
P._Future__chainForeignFuture_closure1.prototype = {
call$0: function() {
- this.$this._completeError$2(this.e, this.s);
+ this.target._completeError$2(this.e, this.s);
},
$signature: 0
};
@@ -6887,11 +6866,11 @@
cancel$0: function() {
var _this = this;
if (_this._target == null)
- return $.$get$nullFuture();
+ return null;
_this._unlisten$0();
_this._target = null;
_this.set$_html$_onData(null);
- return $.$get$nullFuture();
+ return null;
},
onData$1: function(handleData) {
var t1, _this = this;
@@ -7303,6 +7282,9 @@
else if ((t3 & 3) === 0)
t2._ensurePendingEvents$0().add$1(0, new P._DelayedError(error, stackTrace));
t1.close$0(0);
+ t1 = t1._onConnected;
+ if (t1.future._state === 0)
+ t1.completeError$1(error);
},
$signature: 1
};
@@ -7405,7 +7387,7 @@
_inherit(J.JSUnmodifiableArray, J.JSArray);
_inheritMany(J.JSNumber, [J.JSInt, J.JSDouble]);
_inheritMany(P.Error, [H.LateError, H.NotNullableError, P.TypeError, H.JsNoSuchMethodError, H.UnknownJsTypeError, H.RuntimeError, P.AssertionError, H._Error, P.JsonUnsupportedObjectError, P.NullThrownError, P.ArgumentError, P.UnsupportedError, P.UnimplementedError, P.StateError, P.ConcurrentModificationError, P.CyclicInitializationError]);
- _inheritMany(H.Closure, [H.nullFuture_closure, H.TearOffClosure, H.initHooks_closure, H.initHooks_closure0, H.initHooks_closure1, P._AsyncRun__initializeScheduleImmediate_internalCallback, P._AsyncRun__initializeScheduleImmediate_closure, P._AsyncRun__scheduleImmediateJsOverride_internalCallback, P._AsyncRun__scheduleImmediateWithSetImmediate_internalCallback, P._TimerImpl_internalCallback, P._awaitOnObject_closure, P._awaitOnObject_closure0, P._wrapJsFunctionForAsync_closure, P._Future__addListener_closure, P._Future__prependListeners_closure, P._Future__chainForeignFuture_closure, P._Future__chainForeignFuture_closure0, P._Future__chainForeignFuture_closure1, P._Future__asyncCompleteWithValue_closure, P._Future__chainFuture_closure, P._Future__asyncCompleteError_closure, P._Future__propagateToListeners_handleWhenCompleteCallback, P._Future__propagateToListeners_handleWhenCompleteCallback_closure, P._Future__propagateToListeners_handleValueCallback, P._Future__propagateToListeners_handleError, P.Stream_length_closure, P.Stream_length_closure0, P.Stream_first_closure, P.Stream_first_closure0, P._StreamController__subscribe_closure, P._StreamController__recordCancel_complete, P._BufferingStreamSubscription_asFuture_closure, P._BufferingStreamSubscription_asFuture_closure0, P._BufferingStreamSubscription_asFuture__closure, P._BufferingStreamSubscription__sendError_sendError, P._BufferingStreamSubscription__sendDone_sendDone, P._PendingEvents_schedule_closure, P._cancelAndValue_closure, P._rootHandleUncaughtError_closure, P._RootZone_bindCallback_closure, P._RootZone_bindCallbackGuarded_closure, P._RootZone_bindUnaryCallbackGuarded_closure, P.MapBase_mapToString_closure, P._JsonStringifier_writeMap_closure, P.Duration_toString_sixDigits, P.Duration_toString_twoDigits, W.HttpRequest_request_closure, W._EventStreamSubscription_closure, W._EventStreamSubscription_onData_closure, P._AcceptStructuredClone_walk_closure, P._convertDartToNative_Value_closure, P.convertDartToNative_Dictionary_closure, P.promiseToFuture_closure, P.promiseToFuture_closure0, F.Logger_Logger_closure, M.SseClient_closure, M.SseClient_closure0, M.SseClient_closure1, M.SseClient__closure, T.generateUuidV4__generateBits, T.generateUuidV4__printDigits, T.generateUuidV4__bitsDigits, E.main_closure, E.main_closure0]);
+ _inheritMany(H.Closure, [H.closure, H.TearOffClosure, H.initHooks_closure, H.initHooks_closure0, H.initHooks_closure1, P._AsyncRun__initializeScheduleImmediate_internalCallback, P._AsyncRun__initializeScheduleImmediate_closure, P._AsyncRun__scheduleImmediateJsOverride_internalCallback, P._AsyncRun__scheduleImmediateWithSetImmediate_internalCallback, P._TimerImpl_internalCallback, P._awaitOnObject_closure, P._awaitOnObject_closure0, P._wrapJsFunctionForAsync_closure, P._Future__addListener_closure, P._Future__prependListeners_closure, P._Future__chainForeignFuture_closure, P._Future__chainForeignFuture_closure0, P._Future__chainForeignFuture_closure1, P._Future__asyncCompleteWithValue_closure, P._Future__chainFuture_closure, P._Future__asyncCompleteError_closure, P._Future__propagateToListeners_handleWhenCompleteCallback, P._Future__propagateToListeners_handleWhenCompleteCallback_closure, P._Future__propagateToListeners_handleValueCallback, P._Future__propagateToListeners_handleError, P.Stream_length_closure, P.Stream_length_closure0, P.Stream_first_closure, P.Stream_first_closure0, P._StreamController__subscribe_closure, P._StreamController__recordCancel_complete, P._BufferingStreamSubscription_asFuture_closure, P._BufferingStreamSubscription_asFuture_closure0, P._BufferingStreamSubscription_asFuture__closure, P._BufferingStreamSubscription__sendError_sendError, P._BufferingStreamSubscription__sendDone_sendDone, P._PendingEvents_schedule_closure, P._cancelAndValue_closure, P._rootHandleUncaughtError_closure, P._RootZone_bindCallback_closure, P._RootZone_bindCallbackGuarded_closure, P._RootZone_bindUnaryCallbackGuarded_closure, P.MapBase_mapToString_closure, P._JsonStringifier_writeMap_closure, P.Duration_toString_sixDigits, P.Duration_toString_twoDigits, W.HttpRequest_request_closure, W._EventStreamSubscription_closure, W._EventStreamSubscription_onData_closure, P._AcceptStructuredClone_walk_closure, P._convertDartToNative_Value_closure, P.convertDartToNative_Dictionary_closure, P.promiseToFuture_closure, P.promiseToFuture_closure0, F.Logger_Logger_closure, M.SseClient_closure, M.SseClient_closure0, M.SseClient_closure1, M.SseClient__closure, T.generateUuidV4__generateBits, T.generateUuidV4__printDigits, T.generateUuidV4__bitsDigits, E.main_closure, E.main_closure0]);
_inherit(H.EfficientLengthIterable, P.Iterable);
_inheritMany(H.EfficientLengthIterable, [H.ListIterable, H.LinkedHashMapKeyIterable]);
_inherit(H.NullError, P.TypeError);
@@ -7496,7 +7478,6 @@
_ElementEventStreamImpl_legacy_MouseEvent: findType("_ElementEventStreamImpl<MouseEvent*>"),
_EventStream_legacy_Event: findType("_EventStream<Event*>"),
_Future_HttpRequest: findType("_Future<HttpRequest>"),
- _Future_Null: findType("_Future<Null>"),
_Future_dynamic: findType("_Future<@>"),
_Future_int: findType("_Future<int>"),
_Future_void: findType("_Future<~>"),
@@ -7711,7 +7692,7 @@
return H.getIsolateAffinityTag("_$dart_dartClosure");
});
_lazyFinal($, "nullFuture", "$get$nullFuture", function() {
- return C.C__RootZone.run$1$1(new H.nullFuture_closure(), H.findType("Future<Null>"));
+ return C.C__RootZone.run$1$1(new H.closure(), H.findType("Future<Null>"));
});
_lazyFinal($, "TypeErrorDecoder_noSuchMethodPattern", "$get$TypeErrorDecoder_noSuchMethodPattern", function() {
return H.TypeErrorDecoder_extractPattern(H.TypeErrorDecoder_provokeCallErrorOn({
@@ -7732,7 +7713,7 @@
});
_lazyFinal($, "TypeErrorDecoder_nullLiteralCallPattern", "$get$TypeErrorDecoder_nullLiteralCallPattern", function() {
return H.TypeErrorDecoder_extractPattern(function() {
- var $argumentsExpr$ = "$arguments$";
+ var $argumentsExpr$ = '$arguments$';
try {
null.$method$($argumentsExpr$);
} catch (e) {
@@ -7745,7 +7726,7 @@
});
_lazyFinal($, "TypeErrorDecoder_undefinedLiteralCallPattern", "$get$TypeErrorDecoder_undefinedLiteralCallPattern", function() {
return H.TypeErrorDecoder_extractPattern(function() {
- var $argumentsExpr$ = "$arguments$";
+ var $argumentsExpr$ = '$arguments$';
try {
(void 0).$method$($argumentsExpr$);
} catch (e) {
@@ -7781,7 +7762,7 @@
return P._AsyncRun__initializeScheduleImmediate();
});
_lazyFinal($, "Future__nullFuture", "$get$Future__nullFuture", function() {
- return type$._Future_Null._as($.$get$nullFuture());
+ return H.findType("_Future<Null>")._as($.$get$nullFuture());
});
_lazy($, "_hasErrorStackProperty", "$get$_hasErrorStackProperty", function() {
return new Error().stack != void 0;
@@ -7830,7 +7811,7 @@
callback(null);
return;
}
- if (typeof document.currentScript != "undefined") {
+ if (typeof document.currentScript != 'undefined') {
callback(document.currentScript);
return;
}
@@ -7844,11 +7825,10 @@
scripts[i].addEventListener("load", onLoad, false);
})(function(currentScript) {
init.currentScript = currentScript;
- var callMain = E.main;
if (typeof dartMainRunner === "function")
- dartMainRunner(callMain, []);
+ dartMainRunner(E.main, []);
else
- callMain([]);
+ E.main([]);
});
})();