Unverified Commit 0f1d0e39 authored by Alex Li's avatar Alex Li Committed by GitHub

🎨 Improve exceptions thrown by asset bundle (#114313)

parent c2edb20f
...@@ -81,9 +81,6 @@ abstract class AssetBundle { ...@@ -81,9 +81,6 @@ abstract class AssetBundle {
/// isolate to avoid jank on the main thread. /// isolate to avoid jank on the main thread.
Future<String> loadString(String key, { bool cache = true }) async { Future<String> loadString(String key, { bool cache = true }) async {
final ByteData data = await load(key); final ByteData data = await load(key);
if (data == null) {
throw FlutterError('Unable to load asset: $key');
}
// 50 KB of data should take 2-3 ms to parse on a Moto G4, and about 400 μs // 50 KB of data should take 2-3 ms to parse on a Moto G4, and about 400 μs
// on a Pixel 4. // on a Pixel 4.
if (data.lengthInBytes < 50 * 1024) { if (data.lengthInBytes < 50 * 1024) {
...@@ -139,7 +136,7 @@ class NetworkAssetBundle extends AssetBundle { ...@@ -139,7 +136,7 @@ class NetworkAssetBundle extends AssetBundle {
final HttpClientResponse response = await request.close(); final HttpClientResponse response = await request.close();
if (response.statusCode != HttpStatus.ok) { if (response.statusCode != HttpStatus.ok) {
throw FlutterError.fromParts(<DiagnosticsNode>[ throw FlutterError.fromParts(<DiagnosticsNode>[
ErrorSummary('Unable to load asset: $key'), _errorSummaryWithKey(key),
IntProperty('HTTP status code', response.statusCode), IntProperty('HTTP status code', response.statusCode),
]); ]);
} }
...@@ -255,7 +252,10 @@ class PlatformAssetBundle extends CachingAssetBundle { ...@@ -255,7 +252,10 @@ class PlatformAssetBundle extends CachingAssetBundle {
final ByteData? asset = final ByteData? asset =
await ServicesBinding.instance.defaultBinaryMessenger.send('flutter/assets', encoded.buffer.asByteData()); await ServicesBinding.instance.defaultBinaryMessenger.send('flutter/assets', encoded.buffer.asByteData());
if (asset == null) { if (asset == null) {
throw FlutterError('Unable to load asset: $key'); throw FlutterError.fromParts(<DiagnosticsNode>[
_errorSummaryWithKey(key),
ErrorDescription('The asset does not exist or has empty data.'),
]);
} }
return asset; return asset;
} }
...@@ -284,8 +284,11 @@ class PlatformAssetBundle extends CachingAssetBundle { ...@@ -284,8 +284,11 @@ class PlatformAssetBundle extends CachingAssetBundle {
} }
try { try {
return await ui.ImmutableBuffer.fromAsset(key); return await ui.ImmutableBuffer.fromAsset(key);
} on Exception { } on Exception catch (e) {
throw FlutterError('Unable to load asset: $key.'); throw FlutterError.fromParts(<DiagnosticsNode>[
_errorSummaryWithKey(key),
ErrorDescription(e.toString()),
]);
} }
} }
} }
...@@ -294,6 +297,10 @@ AssetBundle _initRootBundle() { ...@@ -294,6 +297,10 @@ AssetBundle _initRootBundle() {
return PlatformAssetBundle(); return PlatformAssetBundle();
} }
ErrorSummary _errorSummaryWithKey(String key) {
return ErrorSummary('Unable to load asset: "$key".');
}
/// The [AssetBundle] from which this application was loaded. /// The [AssetBundle] from which this application was loaded.
/// ///
/// The [rootBundle] contains the resources that were packaged with the /// The [rootBundle] contains the resources that were packaged with the
......
...@@ -27,6 +27,8 @@ class TestAssetBundle extends CachingAssetBundle { ...@@ -27,6 +27,8 @@ class TestAssetBundle extends CachingAssetBundle {
} }
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized();
test('Caching asset bundle test', () async { test('Caching asset bundle test', () async {
final TestAssetBundle bundle = TestAssetBundle(); final TestAssetBundle bundle = TestAssetBundle();
...@@ -72,8 +74,8 @@ void main() { ...@@ -72,8 +74,8 @@ void main() {
expect( expect(
error.toStringDeep(), error.toStringDeep(),
'FlutterError\n' 'FlutterError\n'
' Unable to load asset: key\n' ' Unable to load asset: "key".\n'
' HTTP status code: 404\n', ' HTTP status code: 400\n',
); );
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/39998 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/39998
...@@ -83,4 +85,20 @@ void main() { ...@@ -83,4 +85,20 @@ void main() {
expect(bundle.toString(), 'NetworkAssetBundle#${shortHash(bundle)}($uri)'); expect(bundle.toString(), 'NetworkAssetBundle#${shortHash(bundle)}($uri)');
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/39998 }, skip: isBrowser); // https://github.com/flutter/flutter/issues/39998
test('Throws expected exceptions when loading not exists asset', () async {
late final FlutterError error;
try {
await rootBundle.load('not-exists');
} on FlutterError catch (e) {
error = e;
}
expect(
error.message,
equals(
'Unable to load asset: "not-exists".\n'
'The asset does not exist or has empty data.',
),
);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/56314
} }
...@@ -1997,7 +1997,13 @@ void main() { ...@@ -1997,7 +1997,13 @@ void main() {
find.byKey(key), find.byKey(key),
matchesGoldenFile('image_test.missing.1.png'), matchesGoldenFile('image_test.missing.1.png'),
); );
expect(tester.takeException().toString(), startsWith('Unable to load asset: ')); expect(
tester.takeException().toString(),
equals(
'Unable to load asset: "missing-asset".\n'
'The asset does not exist or has empty data.',
),
);
await tester.pump(); await tester.pump();
await expectLater( await expectLater(
find.byKey(key), find.byKey(key),
......
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