-1
ImagePicker _picker = ImagePicker(); // from image_picker.dart

try {
      XFile? pickedFile = await _picker.pickImage(source: source);
      do xyz;
}
catch (e){
      ...something
}

vs

try {
      _picker.pickImage(source: source).then((file) {do xyz;});
}
catch (e){
      ...something
}

The file select dialog opens. If I cancel without selecting a file, this is the behavior:

Case 1: await - neither 'do xyz' or the catch block is executed - the function just returns

case 2: then - the 'do xyz' block is executed

What is going on?

Sunil Gupta
  • 666
  • 6
  • 20
  • Can you provide a reproducible example? There should not be any different with respect to `do xyz`. The `try`/`catch` blocks in the two examples are not equivalent, however. – jamesdlin Mar 02 '22 at 04:57
  • To be clear: please provide [minimal reproducible examples](https://stackoverflow.com/help/minimal-reproducible-example) that other people can run to observe the behavior you claim. As your question currently stands, it seems very likely that you are *not* performing a proper apples-to-apples comparison and likely are misinterpreting your observations. – jamesdlin Mar 02 '22 at 20:01

1 Answers1

0

What you claim is just not possible. The do xyz line in the first example will execute if it executes in the second example. It will just execute a bit later in time.

These two examples are quite similar but there is one difference: the second one's try/catch does not catch the async errors here. To fix that and to make the two examples exactly the same, you need to add an await to the second one. Now these two are exactly the same:

try {
      XFile? pickedFile = await _picker.pickImage(source: source);
      do xyz;
}
catch (e){
      ...something
}
try {
      await _picker.pickImage(source: source).then((file) {do xyz;});
}
catch (e){
      ...something
}

Because otherwise you initiate an async job but not await it, the execution gets out of the try/catch immediately and it cannot catch errors that will happen later.

Gazihan Alankus
  • 11,256
  • 7
  • 46
  • 57
  • var pickedFile = await _picker.pickImage(source: source); var abc = 5; the abc=5 line gets called only if I pick a file. – Sunil Gupta Mar 02 '22 at 07:39
  • also now adding the await as in await _picker.pickImage(source: source).then((pf) { pickedFile = pf; }); var abc = 5; again abc=5 is not called... – Sunil Gupta Mar 02 '22 at 07:46
  • that's what's supposed to be. until you pick a file that future does not complete. in your second example the do xyz does not execute until you pick a file, either. – Gazihan Alankus Mar 02 '22 at 07:54
  • got that - but if I 'cancel' and do not pick a file I'm supposed to know that. The documentation says if a file is not picked it will return null.... – Sunil Gupta Mar 02 '22 at 08:21
  • The behavior is equivalent to the event not having been fired at all - as if that thread just dies – Sunil Gupta Mar 02 '22 at 08:28
  • @SunilGupta Please provide real code that reproduces the behavior you're observing. `await` is syntactic sugar for registering a `Future.then` callback. If no exception is thrown, there should not be any difference in behavior. – jamesdlin Mar 02 '22 at 08:31
  • onDoubleTap: () async { if (!cameraLoading) { buttonPressed = true; << comes here var fd = await _onFileSelectPressed(ImageSource.gallery, context); setState(() { fileData = fd; << does not come here }); } }, ============= Future _onFileSelectPressed(ImageSource source) async { XFile? pickedFile; try { await _picker.pickImage(source: source).then((pf) { pickedFile = pf; << does not execute }); if (pickedFile != null) { << does not execute – Sunil Gupta Mar 02 '22 at 08:44
  • When you cancel you get null. So it won't go into if (pickedFile != null) when you cancel. You are confused there. Put more ifs and breakpoints, you'll realize that when you cancel those lines actually execute and give you null. – Gazihan Alankus Mar 02 '22 at 11:21
  • @GazihanAlankus - I do know that (pickedFile != null) will not execute - but you will agree that the expression has to be evaluated, right? So, the debugger "next" must go to that line and THEN skip the if block. The debugger does not go anywhere, not even the pickedFile = pf portion that is after the .then – Sunil Gupta Mar 03 '22 at 08:04
  • You should add print lines there and not expect debugger next to show you each line. Sometimes things may be optimized away. – Gazihan Alankus Mar 03 '22 at 08:37