flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
162.18k stars 26.64k forks source link

[go_router] canPop() throws "BadState: No element" on error pages (and maybe other pages) #147465

Open quaaantumdev opened 2 weeks ago

quaaantumdev commented 2 weeks ago

Steps to reproduce

  1. Implement errorBuilder for GoRouter with some CustomErrorPage() widget.
  2. Check if you can pop the page inside the CustomErrorPage() by accessing GoRouter.of(context).canPop() inside the build(..) function of your CustomErrorPage
  3. Navigate to any URL that does not exist (which should bring up the error page on an empty route match list)

Expected results

Expecting GoRouter.of(context).canPop() to return false if there is not even a single page to pop.

Actual results

Accessing canPop() will crash with Bad state: No element .

One may also trigger this error in other ways, that is just the way I discovered it. I wanted to use my default Header on my error page, which internally checks if it should display a back button, resulting in this error. I guess this is a pretty common use case.

The Problem seems to be, that GoRouter.canPop delegates it to routerDelegate.canPop() which then tries to get the "last" match by accessing currentConfiguration.matches.last. This throws as there are no matches. The implementation of Navigator.canPop() returns false if there is no route, so i guess it should be changed to currentConfiguration.matches.lastOrNull and return false if no route was found. But whatever value it may return from your point of view, throwing (by accident, i'd say) seems really wrong.

Code sample

Initialize GoRouter ```dart // MaterialApp.router(... GoRouter( // ... your config errorBuilder: (context, state) => CustomErrorPage( routerState: state, ), ) /// a custom error page class CustomErrorPage extends StatelessWidget { final GoRouterState routerState; const GoErrorPage({ super.key, required this.routerState, }); @override Widget build(BuildContext context) { final canPop = GoRouter.of(context).canPop(); // <-- this will crash // show a back button if one can pop ... return Text("Hello there"); } } ```

Screenshots or Video

No response

Logs

No response

Flutter Doctor output

Doctor output ```console Doctor summary (to see all details, run flutter doctor -v): [√] Flutter (Channel stable, 3.19.6, on Microsoft Windows [Version 10.0.19045.4291], locale en-GB) [√] Windows Version (Installed version of Windows is version 10 or higher) [√] Android toolchain - develop for Android devices (Android SDK version 34.0.0) [√] Chrome - develop for the web [√] Visual Studio - develop Windows apps (Visual Studio Build Tools 2019 16.11.32) [√] Android Studio (version 2023.1) [√] VS Code (version 1.88.0) [√] Connected device (4 available) [√] Network resources • No issues found! ```
darshankawar commented 2 weeks ago

@quaaantumdev Can you provide complete runnable code sample that we can directly copy paste and run to verify this further ? Also provide the entire error log.

quaaantumdev commented 1 week ago

@darshankawar we created a sample app showing the issue: https://github.com/quaaantumdev/gorouter_canpop_issue

HomePage works as expected:

image

Pressing the button tries to navigate to a route that does not exist, resulting in the CustomErrorPage. This Error Page utilizes the same CustomPageHeaderSliver, which checks GoRouter.of(context.canPop(), which will therefore fail. We catch this exception in the example to show it in the ui:

image

And here is your error log from the CustomErrorPage --> CustomPageHeaderSliver.build() --> GoRouter.of(context).canPop()

Bad state: No element
#0      _Array.last (dart:core-patch/array.dart:56:5)
#1      GoRouterDelegate.canPop (package:go_router/src/delegate.dart:89:58)
#2      GoRouter.canPop (package:go_router/src/router.dart:321:35)
#3      CustomPageHeaderSliver.build (package:gorouter_canpop_issue/main.dart:115:37)
#4      StatelessElement.build (package:flutter/src/widgets/framework.dart:5550:49)
#5      ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:5480:15)
#6      Element.rebuild (package:flutter/src/widgets/framework.dart:5196:7)
#7      ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:5462:5)
#8      ComponentElement.mount (package:flutter/src/widgets/framework.dart:5456:5)
#9      Element.inflateWidget (package:flutter/src/widgets/framework.dart:4335:16)
#10     MultiChildRenderObjectElement.inflateWidget (package:flutter/src/widgets/framework.dart:6893:36)
#11     MultiChildRenderObjectElement.mount (package:flutter/src/widgets/fra
darshankawar commented 1 week ago

Thanks for the update. Seeing the same behavior as reported using the code repo provided.

stable, master flutter doctor -v ``` [!] Flutter (Channel stable, 3.19.6, on macOS 12.2.1 21D62 darwin-x64, locale en-GB) • Flutter version 3.19.6 on channel stable at /Users/dhs/documents/fluttersdk/flutter ! Warning: `flutter` on your path resolves to /Users/dhs/Documents/Fluttersdk/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/dhs/documents/fluttersdk/flutter. Consider adding /Users/dhs/documents/fluttersdk/flutter/bin to the front of your path. ! Warning: `dart` on your path resolves to /Users/dhs/Documents/Fluttersdk/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/dhs/documents/fluttersdk/flutter. Consider adding /Users/dhs/documents/fluttersdk/flutter/bin to the front of your path. • Upstream repository https://github.com/flutter/flutter.git • Framework revision 54e66469a9 (6 days ago), 2024-04-17 13:08:03 -0700 • Engine revision c4cd48e186 • Dart version 3.3.4 • DevTools version 2.31.1 • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades. [!] Xcode - develop for iOS and macOS (Xcode 12.3) • Xcode at /Applications/Xcode.app/Contents/Developer ! Flutter recommends a minimum Xcode version of 13. Download the latest version or update via the Mac App Store. • CocoaPods version 1.11.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] VS Code (version 1.62.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.21.0 [✓] Connected device (5 available) • SM G975F (mobile) • RZ8M802WY0X • android-arm64 • Android 11 (API 30) • Darshan's iphone (mobile) • 21150b119064aecc249dfcfe05e259197461ce23 • ios • iOS 14.4.1 18D61 • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729 • ios • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator) • macOS (desktop) • macos • darwin-x64 • Mac OS X 10.15.4 19E2269 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 98.0.4758.80 [✓] HTTP Host Availability • All required HTTP hosts are available ! Doctor found issues in 1 category. [!] Flutter (Channel master, 3.22.0-22.0.pre.6, on macOS 12.2.1 21D62 darwin-x64, locale en-GB) • Flutter version 3.22.0-22.0.pre.6 on channel master at /Users/dhs/documents/fluttersdk/flutter ! Warning: `flutter` on your path resolves to /Users/dhs/Documents/Fluttersdk/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/dhs/documents/fluttersdk/flutter. Consider adding /Users/dhs/documents/fluttersdk/flutter/bin to the front of your path. ! Warning: `dart` on your path resolves to /Users/dhs/Documents/Fluttersdk/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/dhs/documents/fluttersdk/flutter. Consider adding /Users/dhs/documents/fluttersdk/flutter/bin to the front of your path. • Upstream repository https://github.com/flutter/flutter.git • Framework revision d34d4cd125 (16 minutes ago), 2024-05-02 03:08:30 -0400 • Engine revision fc28057dbd • Dart version 3.5.0 (build 3.5.0-122.0.dev) • DevTools version 2.35.0 • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades. [!] Android toolchain - develop for Android devices (Android SDK version 30.0.3) • Android SDK at /Users/dhs/Library/Android/sdk ✗ cmdline-tools component is missing Run `path/to/sdkmanager --install "cmdline-tools;latest"` See https://developer.android.com/studio/command-line for more details. ✗ Android license status unknown. Run `flutter doctor --android-licenses` to accept the SDK licenses. See https://flutter.dev/docs/get-started/install/macos#android-setup for more details. [✓] Xcode - develop for iOS and macOS (Xcode 13.2.1) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 13C100 • CocoaPods version 1.11.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] IntelliJ IDEA Ultimate Edition (version 2021.3.2) • IntelliJ at /Applications/IntelliJ IDEA.app • Flutter plugin version 65.1.4 • Dart plugin version 213.7228 [✓] VS Code (version 1.62.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.29.0 [✓] Connected device (3 available) • Darshan's iphone (mobile) • 21150b119064aecc249dfcfe05e259197461ce23 • ios • iOS 15.3.1 19D52 • macOS (desktop) • macos • darwin-x64 • macOS 12.2.1 21D62 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 109.0.5414.119 [✓] Network resources • All expected network resources are available. ! Doctor found issues in 1 category. [!] Xcode - develop for iOS and macOS (Xcode 12.3) • Xcode at /Applications/Xcode.app/Contents/Developer ! Flutter recommends a minimum Xcode version of 13. Download the latest version or update via the Mac App Store. • CocoaPods version 1.11.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] VS Code (version 1.62.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.21.0 [✓] Connected device (5 available) • SM G975F (mobile) • RZ8M802WY0X • android-arm64 • Android 11 (API 30) • Darshan's iphone (mobile) • 21150b119064aecc249dfcfe05e259197461ce23 • ios • iOS 14.4.1 18D61 • iPhone 12 Pro Max (mobile) • A5473606-0213-4FD8-BA16-553433949729 • ios • com.apple.CoreSimulator.SimRuntime.iOS-14-3 (simulator) • macOS (desktop) • macos • darwin-x64 • Mac OS X 10.15.4 19E2269 darwin-x64 • Chrome (web) • chrome • web-javascript • Google Chrome 98.0.4758.80 [✓] HTTP Host Availability • All required HTTP hosts are available ! Doctor found issues in 1 category. ```