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

Error on Check_and_refresh_token #62

Closed
JakobAaen opened this issue May 26, 2022 · 8 comments
Closed

Error on Check_and_refresh_token #62

JakobAaen opened this issue May 26, 2022 · 8 comments

Comments

@JakobAaen
Copy link

Getting "string indices must be integers" error on Check_and_refresh_token.

Started happening today. Seems like they did some kind of update for Kia app yesterday, as the app was down for a couple of hours.

@chrisglencross
Copy link

chrisglencross commented Aug 26, 2022

This started happening to me today at the same time that the Kia Connect app reported that my account had exceeded the maximum number of daily checks. I'm changing my monitoring app to turn down the polling frequency to every 30 minutes to see if that stops it happening again.

Edit: It might in general be useful if the library checks the HTTP response status from all calls before trying to interpret the JSON payload, to give a more meaningful error to an application when something goes wrong. For me when this happens the HTTP response code is 509 and the response payload is:

{"retCode":"F","resCode":"5091","resMsg":"Exceeds number of requests - Exceeds Number of Requests.","msgId":"..."}

but the Python API currently swallows this meaningful error information from Kia Connect and instead throws an error "string indices must be integers" because the JSON doesn't contain the expected data.

@ZuinigeRijder
Copy link
Collaborator

ZuinigeRijder commented Sep 18, 2022

I also encounter this error sometimes. Here is the stacktrace when called from my bluelink_monitor:

Traceback (most recent call last):
  File "/home/rick/bluelink_monitor/bluelink_monitor.py", line 74, in <module>
    vm.check_and_refresh_token()
  File "/home/rick/bluelink_monitor/hyundai_kia_connect_api/VehicleManager.py", line 88, in check_and_refresh_token
    self.initialize()
  File "/home/rick/bluelink_monitor/hyundai_kia_connect_api/VehicleManager.py", line 51, in initialize
    self.update_all_vehicles_with_cached_state()
  File "/home/rick/bluelink_monitor/hyundai_kia_connect_api/VehicleManager.py", line 58, in update_all_vehicles_with_cached_state
    self.update_vehicle_with_cached_state(self.get_vehicle(vehicle_id))
  File "/home/rick/bluelink_monitor/hyundai_kia_connect_api/VehicleManager.py", line 61, in update_vehicle_with_cached_state
    self.api.update_vehicle_with_cached_state(self.token, vehicle)
  File "/home/rick/bluelink_monitor/hyundai_kia_connect_api/KiaUvoApiEU.py", line 180, in update_vehicle_with_cached_state
    state = self._get_cached_vehicle_state(token, vehicle)
  File "/home/rick/bluelink_monitor/hyundai_kia_connect_api/KiaUvoApiEU.py", line 335, in _get_cached_vehicle_state
    response = response["resMsg"]["vehicleStatusInfo"]
TypeError: string indices must be integers

As you see, I use KiaUvoApiEU.py and hyundai_kia_connect_api-1.34.2. When I run it again immediately thereafter, it works. Indeed I would expect a try/catch error handling and maybe a retry mechanism?. Or is the idea that the calling program has to catch those type of errors and do a retry? At least I would expect a decent error message what the cause of the not filled data is?

@cdnninja
Copy link
Collaborator

Ideally would love to add proper exceptions on this. Anyone able to drop a PR? This above error happens when the data is missing from the API.

@ZuinigeRijder
Copy link
Collaborator

ZuinigeRijder commented Oct 16, 2022

I have been running hyundai_kia_connect_monitor for a month (28 calls per day, ~840 calls per moonth) with a global try/catch/retry mechanism and the following exceptions have been reported:

30 times:

hyundai_kia_connect_api - Get vehicle location failed
Traceback (most recent call last):
  File "/home/rick/hyundai_kia_connect_monitor/monitor.py", line 73, in get_append_data
    manager.check_and_refresh_token()
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 88, in check_and_refresh_token
    self.initialize()
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 51, in initialize
    self.update_all_vehicles_with_cached_state()
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 58, in update_all_vehicles_with_cached_state
    self.update_vehicle_with_cached_state(self.get_vehicle(vehicle_id))
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 61, in update_vehicle_with_cached_state
    self.api.update_vehicle_with_cached_state(self.token, vehicle)
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/KiaUvoApiEU.py", line 317, in update_vehicle_with_cached_state
    self.get_last_updated_at(get_child_value(state, "vehicleLocation.time")),
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/KiaUvoApiEU.py", line 167, in get_last_updated_at
    m = re.match(r"(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})", value)
  File "/usr/lib/python3.9/re.py", line 191, in match
    return _compile(pattern, flags).match(string)
TypeError: expected string or bytes-like object

39 times:

Exception: string indices must be integers
Traceback (most recent call last):
  File "/home/rick/hyundai_kia_connect_monitor/monitor.py", line 81, in get_append_data
    manager.check_and_force_update_vehicles(600)
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 76, in check_and_force_update_vehicles
    self.update_vehicle_with_cached_state(vehicle)
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 61, in update_vehicle_with_cached_state
    self.api.update_vehicle_with_cached_state(self.token, vehicle)
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/KiaUvoApiEU.py", line 180, in update_vehicle_with_cached_state
    state = self._get_cached_vehicle_state(token, vehicle)
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/KiaUvoApiEU.py", line 335, in _get_cached_vehicle_state
    response = response["resMsg"]["vehicleStatusInfo"]
TypeError: string indices must be integers

6 time:

Traceback (most recent call last):
  File "/home/rick/hyundai_kia_connect_monitor/monitor.py", line 80, in get_append_data
    manager.check_and_refresh_token()
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 88, in check_and_refresh_token
    self.initialize()
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 48, in initialize
    vehicles = self.api.get_vehicles(self.token)
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/KiaUvoApiEU.py", line 154, in get_vehicles
    for entry in response["resMsg"]["vehicles"]:
KeyError: 'resMsg'

2 times:

Traceback (most recent call last):
  File "/home/rick/hyundai_kia_connect_monitor/monitor.py", line 80, in get_append_data
    manager.check_and_refresh_token()
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 88, in check_and_refresh_token
    self.initialize()
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 48, in initialize
    vehicles = self.api.get_vehicles(self.token)
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/KiaUvoApiEU.py", line 151, in get_vehicles
    response = requests.get(url, headers=headers).json()
  File "/usr/lib/python3/dist-packages/requests/models.py", line 900, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/lib/python3/dist-packages/simplejson/__init__.py", line 525, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3/dist-packages/simplejson/decoder.py", line 370, in decode
    obj, end = self.raw_decode(s)
  File "/usr/lib/python3/dist-packages/simplejson/decoder.py", line 400, in raw_decode
    return self.scan_once(s, idx=_w(s, idx).end())
simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

@cdnninja
Copy link
Collaborator

@ZuinigeRijder very cool to see this in use! If you get time to work on error handling in this any contributions are appreciated. I somewhat keep the lights on around here but don't have the time to learn how to do this properly. Later this winter I may though.

@ZuinigeRijder
Copy link
Collaborator

I just have a try/catch/retry around the calls:

    retries = 2
    while retries > 0:
        try:
            # get information and add to comma separated file
            manager = VehicleManager(
                region=int(REGION),
                brand=int(BRAND),
                username=USERNAME,
                password=PASSWORD,
                pin=PIN
            )
            manager.check_and_refresh_token()
            manager.check_and_force_update_vehicles(600)
            # vm.update_all_vehicles_with_cached_state()

            for _, vehicle in manager.vehicles.items():
                writeln(
                    str(vehicle.last_updated_at) +
                    ', ' + str(vehicle.location_longitude) +
                    ', ' + str(vehicle.location_latitude) +
                    ', ' + str(vehicle.engine_is_running) +
                    ', ' + str(vehicle.car_battery_percentage) +
                    ', ' + str(vehicle.odometer) +
                    ', ' + str(vehicle.ev_battery_percentage) +
                    ', ' + str(vehicle.ev_battery_is_charging) +
                    ', ' + str(vehicle.ev_battery_is_plugged_in)
                )
            retries = 0  # successfully end while loop
        except Exception as ex:  # pylint: disable=broad-except
            log('Exception: ' + str(ex))
            traceback.print_exc()
            retries -= 1
            log("Sleeping a minute")
            time.sleep(60)

You could also have this inside the main calls, e.g. check_and_refresh_token() and check_and_force_update_vehicles(600). Not as elegant as by checking contents, but this will at least avoid callers to work around the issue.

@cdnninja
Copy link
Collaborator

cdnninja commented Jan 3, 2023

I don't think retries will fit all use cases. For example in my case it ties up a thread in home assistant. The calling method wants to know when an update fails and will schedule a future retry when it can. Ideally I want to address as many API oddities as we can but I am not sure if failing API is one we can mask without impacting others.

@ZuinigeRijder
Copy link
Collaborator

I agree with that. Already a very good improvement is that now in the Exception most situations are reported, which are valid exceptions. Since 15 December I got the following Exceptions (I did not add the count):

Exception: 'redirectUrl'
Exception: Exceeds number of requests - Exceeds Number of Requests.
Exception: Expecting value: line 1 column 1 (char 0)
Exception: HTTPSConnectionPool(host='prd.eu-ccapi.hyundai.com', port=8080): Max retries exceeded with url: /api/v1/spa/notifications/register (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0xb36b2178>: Failed to establish a new connection: [Errno 110] Connection timed out'))
Exception: HTTPSConnectionPool(host='prd.eu-ccapi.hyundai.com', port=8080): Max retries exceeded with url: /api/v1/user/oauth2/authorize?response_type=code&state=test&client_id=6d477c38-3ca4-4cf3-9557-2a1929a94654&redirect_uri=https://prd.eu-ccapi.hyundai.com:8080/api/v1/user/oauth2/redirect&lang=nl (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0xb37ad1f0>: Failed to establish a new connection: [Errno -5] No address associated with hostname'))
Exception: Request timeout. - Request timeout.
Exception: Unavailable remote control - Service Temporary Unavailable

The following geocode error looks like this is not matched to a correct Exception, but I do not know if it is already solved:

20221227 09:01:37: Exception: Expecting value: line 1 column 1 (char 0)
Traceback (most recent call last):
  File "/home/rick/hyundai_kia_connect_monitor/monitor.py", line 203, in get_append_data
    manager.check_and_refresh_token()
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 93, in check_and_refresh_token
    self.initialize()
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 55, in initialize
    self.update_all_vehicles_with_cached_state()
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 62, in update_all_vehicles_with_cached_state
    self.update_vehicle_with_cached_state(self.get_vehicle(vehicle_id))
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/VehicleManager.py", line 67, in update_vehicle_with_cached_state
    self.api.update_geocoded_location(self.token, vehicle, self.geocode_api_use_email)
  File "/home/rick/hyundai_kia_connect_monitor/hyundai_kia_connect_api/ApiImpl.py", line 83, in update_geocoded_location
    response = response.json()
  File "/usr/lib/python3/dist-packages/requests/models.py", line 900, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/lib/python3/dist-packages/simplejson/__init__.py", line 525, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3/dist-packages/simplejson/decoder.py", line 370, in decode
    obj, end = self.raw_decode(s)
  File "/usr/lib/python3/dist-packages/simplejson/decoder.py", line 400, in raw_decode
    return self.scan_once(s, idx=_w(s, idx).end())
simplejson.errors.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

But I think the best is to close this general issue, because the approach of throwing the correct Exception message is what should be done and is in most cases already done and specific issues should be created for a specific Exceptions which do not match the expected Exceptions, like the last one above.

@cdnninja cdnninja closed this as completed Jan 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants