beeware / toga

A Python native, OS native GUI toolkit.
https://toga.readthedocs.io/en/latest/
BSD 3-Clause "New" or "Revised" License
4.31k stars 668 forks source link

Failure modes of `current_location` request not accomodated #2878

Open freakboy3742 opened 2 days ago

freakboy3742 commented 2 days ago

Describe the bug

According to the Android documentation, it is possible for a one-time location request to fail; in which case, a location of null is returned. However, Toga's location service currently expects that the location is non-null.

Steps to reproduce

This is difficult to reproduce specifically as it depends on a location lookup failure from the location service; however, if your code contains a one-time location request:

location = await self.location.current_location()

it is possible for the underlying getCurrentLocation() call to pass a value of null to the Consumer, resulting in the error:

E/AndroidRuntime: FATAL EXCEPTION: main
E/AndroidRuntime: Process: com.example.astrofilter, PID: 19840
E/AndroidRuntime: com.chaquo.python.PyException: AttributeError: 'NoneType' object has no attribute 'getLatitude'
E/AndroidRuntime:   at <python>.toga_android.hardware.location.toga_location(location.py:17)
E/AndroidRuntime:   at <python>.toga_android.hardware.location.accept(location.py:41)
E/AndroidRuntime:   at <python>.chaquopy_java.call(chaquopy_java.pyx:354)

Expected behavior

If the location service can't obtain a GPS read, it should raise an error rather than crashing.

Screenshots

No response

Environment

Logs

No response

Additional context

iOS/macOS already handles this edge by raising a RuntimeError from the locationManager:didFailWithError: delegate method.

The Android testbed probe currently raises an xfail in the simulate_location_error handler; this should be returning a None result to the consumer (i.e., the same implementation as simulate_current_location, but passing a None value to the accept call).

rmartin16 commented 1 day ago

I was able to reproduce the error by disabling Location in the Android settings within the emulator.

image