Skip to content

Commit ec40aa3

Browse files
nt4f04uNdazatech
authored andcommitted
Add detailed error message for BorderRadiusDirectional (flutter#171805)
<!-- Thanks for filing a pull request! Reviewers are typically assigned within a week of filing a request. To learn more about code review, see our documentation on Tree Hygiene: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md --> This PR adds a more descriptive error message for cases when BorderRadiusDirectional is used in widgets whose ancestors aren't wrapped into Directionality. Fixes flutter#88644 ## Pre-launch Checklist - [X] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [X] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [X] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [X] I signed the [CLA]. - [X] I listed at least one issue that this PR fixes in the description above. - [X] I updated/added relevant documentation (doc comments with `///`). - [X] I added new tests to check the change I am making, or this PR is [test-exempt]. - [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [X] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
1 parent afd5623 commit ec40aa3

5 files changed

Lines changed: 83 additions & 2 deletions

File tree

‎packages/flutter/lib/src/painting/border_radius.dart‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ library;
1111
import 'package:flutter/foundation.dart';
1212

1313
import 'basic_types.dart';
14+
import 'debug.dart';
1415

1516
/// Base class for [BorderRadius] that allows for text-direction aware resolution.
1617
///
@@ -785,7 +786,7 @@ class BorderRadiusDirectional extends BorderRadiusGeometry {
785786

786787
@override
787788
BorderRadius resolve(TextDirection? direction) {
788-
assert(direction != null);
789+
assert(debugCheckCanResolveTextDirection(direction, '$BorderRadiusDirectional'));
789790
switch (direction!) {
790791
case TextDirection.rtl:
791792
return BorderRadius.only(

‎packages/flutter/lib/src/painting/debug.dart‎

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
library;
1717

1818
import 'dart:io';
19-
import 'dart:ui' show Image, Picture, Size;
19+
import 'dart:ui' show Image, Picture, Size, TextDirection;
2020

2121
import 'package:flutter/foundation.dart';
2222

@@ -232,3 +232,40 @@ bool _defaultPictureCapture(Picture picture) => true;
232232
/// Tests may use this to capture the picture and run assertions on it.
233233
ShaderWarmUpImageCallback debugCaptureShaderWarmUpImage = _defaultImageCapture;
234234
bool _defaultImageCapture(Image image) => true;
235+
236+
/// Asserts that a given [TextDirection] is not null.
237+
///
238+
/// Used by painting library classes that require a [TextDirection] to resolve
239+
/// their properties, such as [BorderRadiusDirectional].
240+
///
241+
/// Does nothing if asserts are disabled. Always returns true.
242+
///
243+
/// See also:
244+
///
245+
/// * [debugCheckHasDirectionality], which is a similar widgets-library level function.
246+
bool debugCheckCanResolveTextDirection(TextDirection? direction, String target) {
247+
assert(() {
248+
if (direction == null) {
249+
throw FlutterError.fromParts(<DiagnosticsNode>[
250+
ErrorSummary('No TextDirection found.'),
251+
ErrorDescription(
252+
'To resolve $target properties, it must be provided with a TextDirection.',
253+
),
254+
ErrorHint(
255+
'This error usually occurs when $target is used in a widget without '
256+
'a Directionality ancestor.',
257+
),
258+
ErrorHint(
259+
'Typically, the Directionality widget is introduced by the MaterialApp '
260+
'or WidgetsApp widget at the top of your application widget tree. It '
261+
'determines the ambient reading direction and is used, for example, to '
262+
'determine how to lay out text, how to interpret "start" and "end" '
263+
'values, and to resolve EdgeInsetsDirectional, '
264+
'AlignmentDirectional, and other *Directional objects.',
265+
),
266+
]);
267+
}
268+
return true;
269+
}());
270+
return true;
271+
}

‎packages/flutter/lib/src/widgets/debug.dart‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ bool debugCheckHasMediaQuery(BuildContext context) {
357357
/// hit.
358358
///
359359
/// Does nothing if asserts are disabled. Always returns true.
360+
///
361+
/// See also:
362+
///
363+
/// * [debugCheckHasDirectionality], which is a similar, but more general
364+
/// painting-library level function.
360365
bool debugCheckHasDirectionality(
361366
BuildContext context, {
362367
String? why,

‎packages/flutter/test/painting/border_radius_test.dart‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import 'package:flutter/foundation.dart';
56
import 'package:flutter/painting.dart';
67
import 'package:flutter_test/flutter_test.dart';
78

@@ -330,6 +331,20 @@ void main() {
330331
expect(BorderRadiusDirectional.circular(15.0) % 10.0, BorderRadiusDirectional.circular(5.0));
331332
});
332333

334+
test('BorderRadiusDirectional.resolve with null throws detailed error', () {
335+
const BorderRadiusDirectional borderRadius = BorderRadiusDirectional.all(Radius.circular(1.0));
336+
expect(
337+
() => borderRadius.resolve(null),
338+
throwsA(
339+
isFlutterError.having(
340+
(FlutterError e) => e.message,
341+
'message',
342+
allOf(contains('No TextDirection found.'), contains('without a Directionality ancestor')),
343+
),
344+
),
345+
);
346+
});
347+
333348
test('BorderRadiusDirectional.lerp() invariants', () {
334349
final BorderRadiusDirectional a = BorderRadiusDirectional.circular(10.0);
335350
final BorderRadiusDirectional b = BorderRadiusDirectional.circular(20.0);

‎packages/flutter/test/widgets/container_test.dart‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,29 @@ void main() {
732732
},
733733
);
734734

735+
testWidgets(
736+
'Container with BorderRadiusDirectional and no Directionality throws a detailed error',
737+
(WidgetTester tester) async {
738+
await tester.pumpWidget(
739+
Container(
740+
decoration: BoxDecoration(
741+
border: Border.all(),
742+
borderRadius: const BorderRadiusDirectional.all(Radius.circular(1.0)),
743+
),
744+
),
745+
);
746+
747+
expect(
748+
tester.takeException(),
749+
isFlutterError.having(
750+
(FlutterError e) => e.message,
751+
'message',
752+
allOf(contains('No TextDirection found.'), contains('without a Directionality ancestor')),
753+
),
754+
);
755+
},
756+
);
757+
735758
testWidgets('using clipBehaviour and shadow, should not clip the shadow', (
736759
WidgetTester tester,
737760
) async {

0 commit comments

Comments
 (0)