matanshukry / flutter_google_places_sdk

Flutter plugin for google places native sdk
36 stars 74 forks source link

Web Errors/Exceptions cannot be caught when using parent plugin #11

Closed kaminoan-dev closed 2 years ago

kaminoan-dev commented 2 years ago

First of all, thank you very much for this package which actually works for Flutter Web, it should be ranked much higher when searching in pub.dev.

When using the parent plugin flutter_google_places_sdk in a web platform (Flutter web project) it seems it is not possible to correctly catch errors/exceptions that are thrown at lower levels of the code. Although they are caught, the execution stops.

// The underlying Google Places API SDK using an invalid API key.
final FlutterGooglePlacesSdk googlePlacesApi = new FlutterGooglePlacesSdk("");

try {
      // Get the query response.
      print("Launching autocomplete query...");
      final FindAutocompletePredictionsResponse response = await googlePlacesApi.findAutocompletePredictions(
        input,
        countries: ['it'],
        placeTypeFilter: sdk.PlaceTypeFilter.ADDRESS,
      );
} catch (e) {
      print("Autocomplete query response FAILED");

      final String error = e.toString();
      if (error.contains('INVALID_REQUEST')) {
        // Indicate the API request was malformed, generally due to the missing input.
        print("Autocomplete API request was malformed");
      } else if (error.contains('OVER_QUERY_LIMIT')) {
        // Indicate exceeded the QPS limits or billing not enabled or a self-imposed usage cap exceeded, ...
        print("Autocomplete API query limit exceeded");
      } else if (error.contains('REQUEST_DENIED')) {
        // Indicate the request has been denied because API key is invalid.
        print("Autocomplete API key is invalid");
      } else {
        print("UNKNOWN error <$e>");
      }
}

Launching the following error:

You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account For more information on authentication and Google Maps JavaScript API services please see: https://developers.google.com/maps/documentation/javascript/get-api-key
FlutterGooglePlacesSdk::call error: MapsRequestError: PLACES_AUTOCOMPLETE: REQUEST_DENIED: The application is not allowed to use the Place Service.
Error: MapsRequestError: PLACES_AUTOCOMPLETE: REQUEST_DENIED: The application is not allowed to use the Place Service.

    at Object.createErrorWithStack (http://localhost:45563/dart_sdk.js:5076:12)
    at Object._rethrow (http://localhost:45563/dart_sdk.js:40477:16)
    at async._AsyncCallbackEntry.new.callback (http://localhost:45563/dart_sdk.js:40473:13)
    at Object._microtaskLoop (http://localhost:45563/dart_sdk.js:40330:13)
    at _startMicrotaskLoop (http://localhost:45563/dart_sdk.js:40336:13)
    at http://localhost:45563/dart_sdk.js:35811:9

While the equivalent code can be correctly executed when directly using the flutter_google_places_web package. The error is caught and the code execution continuous normally.

// The underlying Google Places Web API SDK initialized using an invalid API key.
final FlutterGooglePlacesSdkWebPlugin googlePlacesWebApi = new FlutterGooglePlacesSdkWebPlugin();
googlePlacesApi.initialize("");

try {
      // Get the query response.
      print("Launching autocomplete query...");
      final FindAutocompletePredictionsResponse response = await googlePlacesWebApi.findAutocompletePredictions(
        input,
        countries: ['it'],
        placeTypeFilter: sdk.PlaceTypeFilter.ADDRESS,
      );
} catch (e) {
      print("Autocomplete query response FAILED");

      final String error = e.toString();
      if (error.contains('INVALID_REQUEST')) {
        // Indicate the API request was malformed, generally due to the missing input.
        print("Autocomplete API request was malformed");
      } else if (error.contains('OVER_QUERY_LIMIT')) {
        // Indicate exceeded the QPS limits or billing not enabled or a self-imposed usage cap exceeded, ...
        print("Autocomplete API query limit exceeded");
      } else if (error.contains('REQUEST_DENIED')) {
        // Indicate the request has been denied because API key is invalid.
        print("Autocomplete API key is invalid");
      } else {
        print("UNKNOWN error <$e>");
      }
}
matanshukry commented 2 years ago

@Kaminoan-Dev I can't seem to reproduce that. Specifically, you can look at the example under flutter_google_places_sdk - and launch it on web. Both in debug and run, when you don't provider the key - you'll get the error showing up on the UI.

That can only happen if the catch block, much like yours, is executed - since there it will assign the error that will then be shown in the UI. I tried again and it works on both debug and run modes.

And much like in your description, that example project has dependency on flutter_google_places_sdk rather than directly on the web dependency.

Can you make a reproducible example? Or perhaps a gist of the differences you can make in the example, as to when the catch block does not execute?

kaminoan-dev commented 2 years ago

(I have updated my initial post for more details)

I kept getting the same error using the example app in the flutter_google_places_sdk project with a clean clone of the repo. I have then done a fresh intallation of everthing (Android Studio, Flutter, Dart, the package repository, etc) on Windows, since I though it may be relate somehow to using the Linux/Ubuntu version of Chrome... and I still get those error.

As I say, I have just cloned this repository without any modifications of the code and get those errors.

matanshukry commented 2 years ago

@Kaminoan-Dev you mentioned you keep getting "those errors" while using the repository without any modifications.

To be clear then - you're not seeing the error on the web?

Attaching image to what is hapenning, which is what should happen. image

kaminoan-dev commented 2 years ago

Using the repository without any modifications and leaving the API_KEY = '' I do get the same error as in you have in your screenshot. That works perfectly.

However, if it is replaced by an invalid value to force another type of error, for example API_KEY = 'DummyKeyValue', the low level error is not caught and the execution gets stuck.

matanshukry commented 2 years ago

This is an issue with flutter (or rather, dart). Created ticket with flutter: https://github.com/flutter/flutter/issues/97082 which in turn created ticket with dart: https://github.com/dart-lang/sdk/issues/48239

kaminoan-dev commented 2 years ago

Thank you very much. I will subscribe to those issues to follow.

matanshukry commented 2 years ago

@Kaminoan-Dev flutter issue closed with a comment saying it's a valid behavior.

Looking again I agree; the promise it self is never completed in javascript either (neither successfully nor with an error), so it make sense for the dart code to never complete the future either.

Closing as well.