natsuk4ze / gal

How to Save Image or Video to Photo Gallery in Flutter
https://pub.dev/packages/gal
BSD 3-Clause "New" or "Revised" License
105 stars 16 forks source link

Many of my android users report me this error - An unexpected error has occurred #188

Closed alexislg2 closed 9 months ago

alexislg2 commented 9 months ago

Descrpition

I use gal 2.2.0 with flutter 3.16.4 I use gal to save photos downloaded from the internet. I have tried my app on several different phones and it works nicely. Unfortunately, at least 3 of my users experience this error "An unexpected error has occurred"

Here is my code:

await Gal.requestAccess(toAlbum: true);
final uri = Uri.parse(image_url);
final extension = path.extension(uri.path);
final filePath = '${Directory.systemTemp.path}/file.$extension';
await Dio().download(sending.image, filePath);
try {
  await Gal.putImage(filePath, album: "Familink");
  Fluttertoast.cancel();
  if (!context.mounted) return;
  Fluttertoast.showToast(
      msg: S.of(context).saved,
      toastLength: Toast.LENGTH_LONG,
      gravity: ToastGravity.CENTER,
      timeInSecForIosWeb: 1,
      fontSize: 16.0);
  break;
} on GalException catch (e) {
  Fluttertoast.cancel();
  if (!context.mounted) return;
  Fluttertoast.showToast(
      msg: e.type.message,
      toastLength: Toast.LENGTH_LONG,
      gravity: ToastGravity.CENTER,
      timeInSecForIosWeb: 1,
      fontSize: 16.0);
  break;

I have no idea how to debug this

natsuk4ze commented 9 months ago

Hi @alexislg2 👋

👩‍🏫 More detailed debugging information is needed.

Please collect as much of the following data as possible when that error occurs.

When the error becomes reproducible, please submit a Bug Report Issue.

Thanks💚

alexislg2 commented 9 months ago

OK, I don't know yet how to collect that because as I said, I don't have the errors. Only a couple of users reported this to me and sent me the screenshot. I might try with crashalytics

alexislg2 commented 9 months ago

I finally managed to get some stacktrace from crashlytics:

Non-fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: [GalException/UNEXPECTED]: An unexpected error has occurred.. Error thrown gal.
       at MethodChannelGal._invokeMethod(gal_method_channel.dart:16)
       at MethodChannelGal.putImage(gal_method_channel.dart:33)
       at SendingCard.build.<fn>(sending_card.dart:120)
natsuk4ze commented 9 months ago

OK. but there doesn't seem to be any logs that might help identify the cause of the error.

Did you get the GalException.platformException We need all the values of the PlatformException. It is very important because that is where the native code errors are stored.

And if you get more than one error, I would like to know the device and OS trends.

Or is this reproducible?

natsuk4ze commented 9 months ago

By the way, does the 'sending.image' have the correct url value in it?

alexislg2 commented 9 months ago

OK I will release a new version of my app, with more detailed logs in the crashlytics and wait for new logs to come...

This is 100% reproductible. The users who have this error have it 100% of the times, with 100% of the photos they try with.

natsuk4ze commented 9 months ago

I am trying on Android 13 and cannot reproduce the error.

final path = '${Directory.systemTemp.path}/file.jpg';
await Dio().download(
  'https://media.familinkframe.com/resized/2023/12/15/8ec58fe551764bacb2073979e1ee8558.jpg',
  path,
);
await Gal.putImage(path, album: 'Familink');

Is the correct image downloaded in filePath before Gal.putImage?

alexislg2 commented 9 months ago

Solved: the problem was caused by the destination file name: file.jpg

Some rare android devices were not able to overwrite it if a file with a similar name already exists in the album.

new code for downloading:

final uri = Uri.parse(image_url);
final filePath = '${Directory.systemTemp.path}/${uri.pathSegments.last';
await Dio().download(sending.image, filePath);
alexislg2 commented 9 months ago

And by the way, with my original code, the file was named file..jpg instead of file.jpg because path.extension(uri.path) is equal to .jpg, not just jpg.

natsuk4ze commented 9 months ago

I'm glad you were able to resolve the issue 😊 @alexislg2

if a file with a similar name already exists in the album.

Is this not album but directory ? This has nothing to do with the gallery, right?

alexislg2 commented 9 months ago

Downloading a file to the temporary folder if a file already exists was not the issue. The error was raised when trying to save it to the album (only with some devices again):

[GalException/UNEXPECTED]: An unexpected error has occurred.. Error thrown Failed to save image: java.lang.IllegalStateException: Failed to build unique file: /storage/emulated/0/Pictures/Familink/file..jpg

alexislg2 commented 9 months ago

You might consider to update your README. I can make a PR if you like

natsuk4ze commented 9 months ago

[GalException/UNEXPECTED]: An unexpected error has occurred.. Error thrown Failed to save image: java.lang.IllegalStateException: Failed to build unique file: /storage/emulated/0/Pictures/Familink/file..jpg

Was this caused by a duplicate dot in the extension?

alexislg2 commented 9 months ago

I cannot say and I cannot make any test (that would require to push a buggy version of the app in production). According to the error message, I would say it comes from the duplicate

Nevertheless, it's not a good thing to use the same file name as prevent from having multiple photos in the albul

natsuk4ze commented 9 months ago

The MediaStore API and custom java code should avoid duplicates, so duplicate filenames should not be the cause of the error.

Perhaps the file system did not recognize the file correctly because of the two dots in the file extension.

natsuk4ze commented 9 months ago

📝Note

I now know what the "Failed to build unique file" error message means.

If you try to save a file with a duplicate name, the system avoids this automatically. This is of the form "file(1).jpg". At this time, the system will probably separate the name from the extension by the position of the dot in the extension to generate a unique name. That's why it became such an error when there were two extension dots, as in this case.

Lo4D commented 8 months ago

I have encountered this same error. In my case I use Gal.putImageBytes() and it saves image as image.png. Everything was fine, until the image(32).png, meaning that image(31).png is created perfectly fine, but next one is not. I've tested it by deleting image(31).png and it worked fine again, but not after it. I'm testing on POCO F4 with android 13.

I think I'll need to write image to temporary dir with mine own generated name and only then use Gal. But please, consider adding a String name = 'image.png' as a putImageBytes() paramater.

natsuk4ze commented 8 months ago

But please, consider adding a String name = 'image.png' as a putImageBytes() paramater.

Please consider submitting an issue that includes reproducible code. Without it, I can do nothing.