Unverified Commit 5113c50a authored by chunhtai's avatar chunhtai Committed by GitHub

improve error message for navigator page api (#73153)

parent 119e0ea1
...@@ -3310,10 +3310,35 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res ...@@ -3310,10 +3310,35 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
@override @override
void initState() { void initState() {
super.initState(); super.initState();
assert( assert((){
widget.pages.isEmpty || widget.onPopPage != null, if (widget.pages != const <Page<dynamic>>[]) {
'The Navigator.onPopPage must be provided to use the Navigator.pages API', // This navigator uses page API.
if (widget.pages.isEmpty) {
FlutterError.reportError(
FlutterErrorDetails(
exception: FlutterError(
'The Navigator.pages must not be empty to use the '
'Navigator.pages API'
),
library: 'widget library',
stack: StackTrace.current,
),
); );
} else if (widget.onPopPage == null) {
FlutterError.reportError(
FlutterErrorDetails(
exception: FlutterError(
'The Navigator.onPopPage must be provided to use the '
'Navigator.pages API'
),
library: 'widget library',
stack: StackTrace.current,
),
);
}
}
return true;
}());
for (final NavigatorObserver observer in widget.observers) { for (final NavigatorObserver observer in widget.observers) {
assert(observer.navigator == null); assert(observer.navigator == null);
observer._navigator = this; observer._navigator = this;
...@@ -3480,10 +3505,35 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res ...@@ -3480,10 +3505,35 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
@override @override
void didUpdateWidget(Navigator oldWidget) { void didUpdateWidget(Navigator oldWidget) {
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
assert( assert((){
widget.pages.isEmpty || widget.onPopPage != null, if (widget.pages != const <Page<dynamic>>[]) {
'The Navigator.onPopPage must be provided to use the Navigator.pages API', // This navigator uses page API.
if (widget.pages.isEmpty) {
FlutterError.reportError(
FlutterErrorDetails(
exception: FlutterError(
'The Navigator.pages must not be empty to use the '
'Navigator.pages API'
),
library: 'widget library',
stack: StackTrace.current,
),
);
} else if (widget.onPopPage == null) {
FlutterError.reportError(
FlutterErrorDetails(
exception: FlutterError(
'The Navigator.onPopPage must be provided to use the '
'Navigator.pages API'
),
library: 'widget library',
stack: StackTrace.current,
),
); );
}
}
return true;
}());
if (oldWidget.observers != widget.observers) { if (oldWidget.observers != widget.observers) {
for (final NavigatorObserver observer in oldWidget.observers) for (final NavigatorObserver observer in oldWidget.observers)
observer._navigator = null; observer._navigator = null;
...@@ -3494,10 +3544,21 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res ...@@ -3494,10 +3544,21 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
_updateEffectiveObservers(); _updateEffectiveObservers();
} }
if (oldWidget.pages != widget.pages && !restorePending) { if (oldWidget.pages != widget.pages && !restorePending) {
assert( assert((){
widget.pages.isNotEmpty, if (widget.pages.isEmpty) {
'To use the Navigator.pages, there must be at least one page in the list.' FlutterError.reportError(
FlutterErrorDetails(
exception: FlutterError(
'The Navigator.pages must not be empty to use the '
'Navigator.pages API'
),
library: 'widget library',
stack: StackTrace.current,
),
); );
}
return true;
}());
_updatePages(); _updatePages();
} }
......
...@@ -2608,6 +2608,79 @@ void main() { ...@@ -2608,6 +2608,79 @@ void main() {
expect(find.text('initial'), findsOneWidget); expect(find.text('initial'), findsOneWidget);
}); });
testWidgets('throw if onPopPage callback is not provided', (WidgetTester tester) async {
final List<TestPage> myPages = <TestPage>[
const TestPage(key: ValueKey<String>('1'), name:'initial'),
const TestPage(key: ValueKey<String>('2'), name:'second'),
const TestPage(key: ValueKey<String>('3'), name:'third'),
];
await tester.pumpWidget(
MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance!.window),
child: Localizations(
locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate
],
child: Directionality(
textDirection: TextDirection.ltr,
child: Navigator(
pages: myPages,
),
),
),
)
);
final dynamic exception = tester.takeException();
expect(exception, isFlutterError);
final FlutterError error = exception as FlutterError;
expect(
error.toStringDeep(),
equalsIgnoringHashCodes(
'FlutterError\n'
' The Navigator.onPopPage must be provided to use the\n'
' Navigator.pages API\n'
''
),
);
});
testWidgets('throw if page list is empty', (WidgetTester tester) async {
final List<TestPage> myPages = <TestPage>[];
final FlutterExceptionHandler? originalOnError = FlutterError.onError;
FlutterErrorDetails? firstError;
FlutterError.onError = (FlutterErrorDetails? detail) {
// We only care about the first error;
firstError ??= detail;
};
await tester.pumpWidget(
MediaQuery(
data: MediaQueryData.fromWindow(WidgetsBinding.instance!.window),
child: Localizations(
locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate
],
child: Directionality(
textDirection: TextDirection.ltr,
child: Navigator(
pages: myPages,
),
),
),
)
);
FlutterError.onError = originalOnError;
expect(
firstError!.exception.toString(),
'The Navigator.pages must not be empty to use the Navigator.pages API',
);
});
testWidgets('can push and pop pages using page api', (WidgetTester tester) async { testWidgets('can push and pop pages using page api', (WidgetTester tester) async {
late Animation<double> secondaryAnimationOfRouteOne; late Animation<double> secondaryAnimationOfRouteOne;
late Animation<double> primaryAnimationOfRouteOne; late Animation<double> primaryAnimationOfRouteOne;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment