Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sentry_asset_bundle uses loadStructuredBinaryData which has a breaking change in latest master channel #1166

Closed
4 of 11 tasks
mario-jerkovic opened this issue Dec 6, 2022 · 10 comments

Comments

@mario-jerkovic
Copy link

Platform:

  • Dart
  • Flutter Android or iOS
  • Flutter Web

IDE:

  • VSCode
  • IntelliJ/AS
  • XCode
  • Other, which one?

split-debug-info and obfuscate (Flutter Android or iOS) or CanvasKit (Flutter Web):

  • Enabled
  • Disabled

Platform installed with:

  • pub.dev
  • GitHub

Output of the command flutter doctor -v below:

[✓] Flutter (Channel master, 3.7.0-3.0.pre.37, on macOS 13.0.1 22A400 darwin-arm64, locale en-HR)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 14.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.3)
[✓] Connected device (3 available)
[✓] HTTP Host Availability

• No issues found!

The version of the SDK (See pubspec.lock):
6.17.0


I have the following issue:

After upgrading to latest flutter version from "master" channel 3.7.0 application fails to compile and output error in console:

Could not build the precompiled application for the device.
Error (Xcode): ../../.pub-cache/hosted/pub.dev/sentry_flutter-6.17.0/lib/src/sentry_asset_bundle.dart:37:7: Error: The non-abstract class 'SentryAssetBundle' is missing implementations for these members:

Same thing happens on iOS and Android

Steps to reproduce:

  • switch flutter channel to master flutter channel master and run flutter upgrade
  • try to build the app on iOS or Android

Actual result:

  • Error launching application

Expected result:

  • Successful application build
@ueman
Copy link
Collaborator

ueman commented Dec 6, 2022

This time it's https://master-api.flutter.dev/flutter/services/AssetBundle/loadStructuredBinaryData.html at fault.

I wonder if there's a way to somehow avoid failure die to interface changes in the future.

@marandaneto marandaneto changed the title Issue with building app sentry_asset_bundle uses loadStructuredBinaryData which has a breaking change in latest master channel Dec 7, 2022
@marandaneto
Copy link
Contributor

Yeah, that's hard to keep up, not sure if there's any alternative as well.
@mario-jerkovic as of now, you can either patch yourself manually or wait for this change to come at least into the beta channel, we can't maintain 3 versions of the SDK (per channel), it's quite a bit of work.

@marandaneto marandaneto added this to the 8.0.0 milestone Dec 7, 2022
@ueman
Copy link
Collaborator

ueman commented Dec 7, 2022

I think this can be fixed just like this method:

@override
// This is an override on Flutter greater than 3.1
// ignore: override_on_non_overriding_member
Future<ImmutableBuffer> loadBuffer(String key) async {
final span = _hub.getSpan()?.startChild(
'file.read',
description: 'AssetBundle.loadBuffer: ${_fileName(key)}',
);
span?.setData('file.path', key);
ImmutableBuffer data;
try {
data = await _loadBuffer(key);
_setDataLength(data, span);
span?.status = SpanStatus.ok();
} catch (exception) {
span?.throwable = exception;
span?.status = SpanStatus.internalError();
rethrow;
} finally {
await span?.finish();
}
return data;
}
Future<ImmutableBuffer> _loadBuffer(String key) async {
try {
return (_bundle as dynamic).loadBuffer(key);
} on NoSuchMethodError catch (_) {
// The loadBuffer method exists as of Flutter greater than 3.1
// Previous versions don't have it, but later versions do.
// We can't use `extends` in order to provide this method because this is
// a wrapper and thus the method call must be forwarded.
// On Flutter versions <=3.1 we can't forward this call and
// just catch the error which is thrown. On later version the call gets
// correctly forwarded.
//
// In case of a NoSuchMethodError we just return an empty list
return ImmutableBuffer.fromUint8List(Uint8List.fromList([]));
}
}
That way it should be compatible with the current stable as well was with the master channel

@marandaneto
Copy link
Contributor

marandaneto commented Dec 7, 2022

I tried but linter didnt allow me, let me double check.

@ueman
Copy link
Collaborator

ueman commented Dec 7, 2022

Something like the following should work

 @override 
 // This is an override on Flutter greater than xxx
 // ignore: override_on_non_overriding_member 
 Future<T> loadStructuredBinaryData(String key, FutureOr<T> Function(ByteData data) parser) async { 
   final span = _hub.getSpan()?.startChild( 
         'file.read', 
         description: 'AssetBundle.loadStructuredBinaryData: ${_fileName(key)}', 
       ); 
  
   span?.setData('file.path', key); 
  
   T data; 
   try { 
     data = await _loadStructuredBinaryData(key, parser); 
     _setDataLength(data, span); 
     span?.status = SpanStatus.ok(); 
   } catch (exception) { 
     span?.throwable = exception; 
     span?.status = SpanStatus.internalError(); 
     rethrow; 
   } finally { 
     await span?.finish(); 
   } 
   return data; 
 } 
 
 // helper method to have a "typesafe" method
 Future<ImmutableBuffer> _loadStructuredBinaryData(String key, FutureOr<T> Function(ByteData data) parser) { 
     // maybe add some error handling here
     // but it's probably not needed, as you wouldn't call this method on earlier flutter versions
     return (_bundle as dynamic).loadStructuredBinaryData(key, parser); 
 } 

or the following would also work by not calling the inner asset bundle:

 @override 
 // This is an override on Flutter greater than xxx
 // ignore: override_on_non_overriding_member 
Future<T> loadStructuredBinaryData<T>(String key, FutureOr<T> Function(ByteData data) parser) async {
     final span = _hub.getSpan()?.startChild( 
         'file.read', 
         description: 'AssetBundle.loadStructuredBinaryData: ${_fileName(key)}', 
       ); 
  
   span?.setData('file.path', key); 
  
   T data; 
   try { 
     final ByteData data = await load(key);
     if (data == null) {
       throw FlutterError('Unable to load asset: $key');
     }
     data = await parser(data);
     _setDataLength(data, span); 
     span?.status = SpanStatus.ok(); 
   } catch (exception) { 
     span?.throwable = exception; 
     span?.status = SpanStatus.internalError(); 
     rethrow; 
   } finally { 
     await span?.finish(); 
   } 
   return data; 
}

@marandaneto
Copy link
Contributor

Thanks @ueman
@mario-jerkovic would you like to open a PR and try this out?

@ueman ueman added the flutter flutter label Dec 7, 2022
@marandaneto
Copy link
Contributor

loadStructuredBinaryData has been removed already.
flutter/flutter@7673108
So closing it for now.

@ueman
Copy link
Collaborator

ueman commented Dec 9, 2022

I bet it's coming back soon

@ueman
Copy link
Collaborator

ueman commented Dec 11, 2022

It's about to be re-landed flutter/flutter#116684

@volgin
Copy link

volgin commented Feb 14, 2023

I see this issue today on a master channel. Tried with both 6.20.1 and sentry 7.0.0-beta.4:

Error (Xcode): ../../.pub-cache/hosted/pub.dev/sentry_flutter-6.20.1/lib/src/sentry_asset_bundle.dart:37:7: Error: The non-abstract class 'SentryAssetBundle' is missing implementations for these members:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

No branches or pull requests

5 participants