@@ -517,33 +517,44 @@ private void stopConnection(String errorMessage) {
517
517
RuntimeException exception = null ;
518
518
this .state .lock ();
519
519
try {
520
+ ConnectionState connectionState = this .state .getConnectionStateUnsynchronized (true );
521
+
522
+ if (connectionState == null )
523
+ {
524
+ this .logger .error ("'stopConnection' called with a null ConnectionState. This is not expected, please file a bug. https://github.com/dotnet/aspnetcore/issues/new?assignees=&labels=&template=bug_report.md" );
525
+ return ;
526
+ }
527
+
520
528
// errorMessage gets passed in from the transport. An already existing stopError value
521
529
// should take precedence.
522
- if (this . state . getConnectionStateUnsynchronized ( false ) .stopError != null ) {
523
- errorMessage = this . state . getConnectionStateUnsynchronized ( false ) .stopError ;
530
+ if (connectionState .stopError != null ) {
531
+ errorMessage = connectionState .stopError ;
524
532
}
525
533
if (errorMessage != null ) {
526
534
exception = new RuntimeException (errorMessage );
527
535
logger .error ("HubConnection disconnected with an error {}." , errorMessage );
528
536
}
529
537
530
- ConnectionState connectionState = this .state .getConnectionStateUnsynchronized (true );
531
- if (connectionState != null ) {
532
- connectionState .cancelOutstandingInvocations (exception );
533
- connectionState .close ();
534
- this .state .setConnectionState (null );
535
- }
538
+ this .state .setConnectionState (null );
539
+ connectionState .cancelOutstandingInvocations (exception );
540
+ connectionState .close ();
536
541
537
542
logger .info ("HubConnection stopped." );
538
- this .state .changeState (HubConnectionState .CONNECTED , HubConnectionState .DISCONNECTED );
543
+ // We can be in the CONNECTING or CONNECTED state here, depending on if the handshake response was received or not.
544
+ // connectionState.close() above will exit the Start call with an error if it's still running
545
+ this .state .changeState (HubConnectionState .DISCONNECTED );
539
546
} finally {
540
547
this .state .unlock ();
541
548
}
542
549
543
550
// Do not run these callbacks inside the hubConnectionStateLock
544
551
if (onClosedCallbackList != null ) {
545
552
for (OnClosedCallback callback : onClosedCallbackList ) {
546
- callback .invoke (exception );
553
+ try {
554
+ callback .invoke (exception );
555
+ } catch (Exception ex ) {
556
+ logger .warn ("Invoking 'onClosed' method failed:" , ex );
557
+ }
547
558
}
548
559
}
549
560
}
@@ -1519,6 +1530,16 @@ public void changeState(HubConnectionState from, HubConnectionState to) {
1519
1530
}
1520
1531
}
1521
1532
1533
+ public void changeState (HubConnectionState to ) {
1534
+ this .lock .lock ();
1535
+ try {
1536
+ logger .debug ("The HubConnection is transitioning from the {} state to the {} state." , this .hubConnectionState , to );
1537
+ this .hubConnectionState = to ;
1538
+ } finally {
1539
+ this .lock .unlock ();
1540
+ }
1541
+ }
1542
+
1522
1543
public void lock () {
1523
1544
this .lock .lock ();
1524
1545
}
0 commit comments