Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/go_router/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 17.5.1

- Fixes a `StateError` ("Bad state: Future already completed") when a route with an `onExit` callback is popped twice before the navigator rebuilds.

## 17.5.0

- Adds route `metadata` support, including inheritance and override behavior with exposure on `GoRouterState`.
Expand Down
8 changes: 8 additions & 0 deletions packages/go_router/lib/src/match.dart
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,15 @@ class ImperativeRouteMatch extends RouteMatch {

/// Called when the corresponding [Route] associated with this route match is
/// completed.
///
/// A route match can be completed more than once when the same route is
/// popped again before the navigator has rebuilt; for example, two back
/// events in quick succession while an `onExit` callback defers the pop to a
/// microtask. Only the first completion is reported; later ones are ignored.
void complete([dynamic value]) {
if (completer.isCompleted) {
return;
}
completer.complete(value);
}

Expand Down
2 changes: 1 addition & 1 deletion packages/go_router/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: go_router
description: A declarative router for Flutter based on Navigation 2 supporting
deep linking, data-driven routes and more
version: 17.5.0
version: 17.5.1
repository: https://github.com/flutter/packages/tree/main/packages/go_router
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+go_router%22

Expand Down
39 changes: 39 additions & 0 deletions packages/go_router/test/on_exit_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,45 @@ void main() {
expect(find.byKey(homeKey), findsNothing);
});

// Regression test for https://github.com/flutter/flutter/issues/191280
testWidgets('popping a route with onExit twice before the navigator rebuilds does not throw', (
WidgetTester tester,
) async {
final homeKey = UniqueKey();
final detailKey = UniqueKey();

final GoRouter router = await createRouter(
<RouteBase>[
GoRoute(
path: '/',
builder: (_, _) => DummyScreen(key: homeKey),
routes: <RouteBase>[
GoRoute(
path: 'detail',
onExit: (_, _) => true,
builder: (_, _) => DummyScreen(key: detailKey),
),
],
),
],
tester,
);

final Future<Object?> pushFuture = router.push('/detail');
await tester.pumpAndSettle();
expect(find.byKey(detailKey), findsOneWidget);

// Two back events arrive before the deferred pop is applied — e.g. a user
// tapping the back button twice in quick succession.
router.pop('first');
router.pop('second');
await tester.pumpAndSettle();

expect(tester.takeException(), isNull);
expect(find.byKey(homeKey), findsOneWidget);
expect(await pushFuture, 'first');
});

// Regression test for https://github.com/flutter/flutter/issues/137829
testWidgets('back button works synchronously with ShellRoute', (WidgetTester tester) async {
var allow = false;
Expand Down