From 719a8858ae271d6062fa4014f83c6891ec27407e Mon Sep 17 00:00:00 2001 From: Max Korbel Date: Fri, 24 Jan 2025 15:33:16 -0800 Subject: [PATCH] Run end of sim actions even after exception --- lib/src/simulator.dart | 20 ++++++++------ test/simulator_test.dart | 58 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 69 insertions(+), 9 deletions(-) diff --git a/lib/src/simulator.dart b/lib/src/simulator.dart index e79c4c796..48829e31f 100644 --- a/lib/src/simulator.dart +++ b/lib/src/simulator.dart @@ -61,7 +61,7 @@ abstract class Simulator { static bool _simulationEndRequested = false; /// Tracks for [_SimulatorException] that are thrown during the simulation. - static List<_SimulatorException> _simExceptions = []; + static final List<_SimulatorException> _simExceptions = []; /// The maximum time the simulation can run. /// @@ -148,8 +148,6 @@ abstract class Simulator { _currentTimestamp = 0; _simulationEndRequested = false; - _simExceptions = []; - _maxSimTime = -1; if (!_preTickController.isClosed) { await _preTickController.close(); @@ -174,6 +172,9 @@ abstract class Simulator { _pendingTimestamps.clear(); _phase = SimulatorPhase.outOfTick; _injectedActions.clear(); + _endOfSimulationActions.clear(); + _simExceptions.clear(); + _pendingList = ListQueue(); // make sure we've already passed the new completer so that listeners can // get the latest @@ -440,13 +441,9 @@ abstract class Simulator { } } + // initially, just log the exceptions for (final err in _simExceptions) { logger.severe(err.exception.toString(), err.exception, err.stackTrace); - - // trigger the end of simulation if an error occurred - _simulationEndedCompleter.complete(); - - throw err.exception; } if (_currentTimestamp >= _maxSimTime && _maxSimTime > 0) { @@ -467,6 +464,13 @@ abstract class Simulator { } _simulationEndedCompleter.complete(); + + // now, rethrow any exceptions now that sim is over and end of sim actions + // have all executed + for (final err in _simExceptions) { + throw err.exception; + } + await simulationEnded; } } diff --git a/test/simulator_test.dart b/test/simulator_test.dart index 8790937b5..222f1ab56 100644 --- a/test/simulator_test.dart +++ b/test/simulator_test.dart @@ -1,4 +1,4 @@ -// Copyright (C) 2021-2024 Intel Corporation +// Copyright (C) 2021-2025 Intel Corporation // Copyright (C) 2024 Adam Rose // SPDX-License-Identifier: BSD-3-Clause // @@ -143,6 +143,62 @@ void main() { expect(endOfSimActionExecuted, isTrue); expect(errorThrown, isTrue); }); + + test('actions still occur when simulation exception is thrown', () async { + var errorThrown = false; + var endOfSimActionExecuted = false; + + Simulator.registerAction( + 100, + () => Simulator.throwException( + Exception('simulator thrown exception'), StackTrace.current)); + Simulator.registerAction(200, () => true); + + Simulator.registerEndOfSimulationAction(() { + endOfSimActionExecuted = true; + }); + + unawaited(Simulator.run().onError((_, __) { + errorThrown = true; + })); + + await Simulator.simulationEnded; + + expect(errorThrown, isTrue); + expect(endOfSimActionExecuted, isTrue); + }); + + test('actions are cleared at Simulator.reset even if exception occurs', + () async { + var endOfSimActionExecuted = false; + var errorThrown = false; + + Simulator.registerAction( + 100, + () => Simulator.throwException( + Exception('simulator thrown exception'), StackTrace.current)); + + Simulator.registerEndOfSimulationAction(() { + endOfSimActionExecuted = true; + }); + + await Simulator.run().onError((_, __) { + errorThrown = true; + }); + + expect(endOfSimActionExecuted, isTrue); + expect(errorThrown, isTrue); + + endOfSimActionExecuted = false; + + await Simulator.reset(); + + Simulator.registerAction(100, () => true); + + await Simulator.run(); + + expect(endOfSimActionExecuted, isFalse); + }); }); test('registered action exception in simulator ends simulation', () async {