@@ -587,16 +587,31 @@ private void RenderInExistingBatch(RenderQueueEntry renderQueueEntry)
587
587
Log . RenderingComponent ( _logger , componentState ) ;
588
588
componentState . RenderIntoBatch ( _batchBuilder , renderQueueEntry . RenderFragment ) ;
589
589
590
+ List < Exception > exceptions = null ;
591
+
590
592
// Process disposal queue now in case it causes further component renders to be enqueued
591
593
while ( _batchBuilder . ComponentDisposalQueue . Count > 0 )
592
594
{
593
595
var disposeComponentId = _batchBuilder . ComponentDisposalQueue . Dequeue ( ) ;
594
596
var disposeComponentState = GetRequiredComponentState ( disposeComponentId ) ;
595
597
Log . DisposingComponent ( _logger , disposeComponentState ) ;
596
- disposeComponentState . DisposeInBatch ( _batchBuilder ) ;
598
+ if ( ! disposeComponentState . TryDisposeInBatch ( _batchBuilder , out var exception ) )
599
+ {
600
+ exceptions ??= new List < Exception > ( ) ;
601
+ exceptions . Add ( exception ) ;
602
+ }
597
603
_componentStateById . Remove ( disposeComponentId ) ;
598
604
_batchBuilder . DisposedComponentIds . Append ( disposeComponentId ) ;
599
605
}
606
+
607
+ if ( exceptions ? . Count > 1 )
608
+ {
609
+ HandleException ( new AggregateException ( "Exceptions were encountered while disposing components." , exceptions ) ) ;
610
+ }
611
+ else if ( exceptions ? . Count == 1 )
612
+ {
613
+ HandleException ( exceptions [ 0 ] ) ;
614
+ }
600
615
}
601
616
602
617
private void RemoveEventHandlerIds ( ArrayRange < ulong > eventHandlerIds , Task afterTaskIgnoreErrors )
@@ -681,6 +696,9 @@ private void UpdateRenderTreeToMatchClientState(ulong eventHandlerId, EventField
681
696
/// <param name="disposing"><see langword="true"/> if this method is being invoked by <see cref="IDisposable.Dispose"/>, otherwise <see langword="false"/>.</param>
682
697
protected virtual void Dispose ( bool disposing )
683
698
{
699
+ // It's important that we handle all exceptions here before reporting any of them.
700
+ // This way we can dispose all components before an error handler kicks in.
701
+ List < Exception > exceptions = null ;
684
702
foreach ( var componentState in _componentStateById . Values )
685
703
{
686
704
Log . DisposingComponent ( _logger , componentState ) ;
@@ -693,11 +711,21 @@ protected virtual void Dispose(bool disposing)
693
711
}
694
712
catch ( Exception exception )
695
713
{
696
- HandleException ( exception ) ;
714
+ exceptions ??= new List < Exception > ( ) ;
715
+ exceptions . Add ( exception ) ;
697
716
}
698
717
}
718
+ }
719
+
720
+ _batchBuilder . Dispose ( ) ;
699
721
700
- _batchBuilder . Dispose ( ) ;
722
+ if ( exceptions ? . Count > 1 )
723
+ {
724
+ HandleException ( new AggregateException ( "Exceptions were encountered while disposing components." , exceptions ) ) ;
725
+ }
726
+ else if ( exceptions ? . Count == 1 )
727
+ {
728
+ HandleException ( exceptions [ 0 ] ) ;
701
729
}
702
730
}
703
731
0 commit comments