fondberg / spotcast

Home assistant custom component to start Spotify playback on an idle chromecast device as well as control spotify connect devices
Apache License 2.0
640 stars 94 forks source link

AttributeError in the core log #443

Closed larhedse closed 1 month ago

larhedse commented 1 month ago

Bug Ticket

Describe the bug

AttributeError: 'NoneType' object has no attribute 'get'

Troubleshooting

Make sure to validate all the elements before submitting the ticket (Exception to the steps marked as optional)

Environment

Configuration

# please remove any sensitive information like cookies and token keys
<insert configuration here>

Service Call

If relevant, provide a yaml of the service call or explain the action taken to replicate the issue.

<insert the yaml of the service call here>

Logs

2024-05-07 12:48:30.241 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/config/custom_components/spotcast/helpers.py", line 102, in run
    return await loop.run_in_executor(executor, pfunc)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/spotcast/__init__.py", line 137, in get_devices
    client = spotcast_controller.get_spotify_client(account)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/spotcast/spotcast_controller.py", line 267, in get_spotify_client
    auth=self.get_token_instance(account).access_token
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/spotcast/spotcast_controller.py", line 256, in get_token_instance
    dc = self.accounts.get(account).get(CONF_SP_DC)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/spotcast/spotcast_controller.py", line 256, in get_token_instance
    dc = self.accounts.get(account).get(CONF_SP_DC)
         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'get'

Additional context

It is an error, but I still have a fully working environment so to speak. Also not, I have had this for some time, just not got around to make this issue text.

fcusson commented 1 month ago

Looks like your co figuration is not properly set can you provide your configuration (with sensitive information redacted)

larhedse commented 1 month ago

Well I did not include this since it is well a bit boring I guess:

# Spotify 
spotcast:
  sp_dc:
  sp_key:
  country: SE
  accounts:
    marianne:
      sp_dc:
      sp_key:
    vardagsrum:
      sp_dc:
      sp_key: 
    sovrum:
      sp_dc:
      sp_key:
fcusson commented 1 month ago

Ok I was thinking there might be a typo. It might look boring but it's very useful for troubleshooting. basically spotcast is trying to call your co fig dictionary but there is one part in the accounting bt section that is not called the way it is expected.

So we get the first level which returns None because it doesn't exist and then it tries to call get, but since the object is none, its unable to.

larhedse commented 1 month ago

Simple question: Could this be "only" related to when HAOS (warm or cold) restart? And if so, would it be possible to add say a delay when started to make sure whatever is needed to be available is just available?

Background on this is from my own sensor for light which is setup in configuration.yaml, where I have to add a minor thing to get it stable without any (re-)start errors in the log: states('sensor.light_home') in ['unavailable', 'unknown', 'none']

larhedse commented 1 month ago

I just found some more in the core log, may or may not help...

2024-05-07 18:05:18.178 ERROR (MainThread) [homeassistant] Error doing job: Task exception was never retrieved
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 467, in _make_request
    six.raise_from(e, None)
  File "<string>", line 3, in raise_from
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 462, in _make_request
    httplib_response = conn.getresponse()
                       ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/http/client.py", line 1423, in getresponse
    response.begin()
  File "/usr/local/lib/python3.12/http/client.py", line 331, in begin
    version, status, reason = self._read_status()
                              ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/http/client.py", line 292, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/socket.py", line 707, in readinto
    return self._sock.recv_into(b)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/ssl.py", line 1252, in recv_into
    return self.read(nbytes, buffer)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/ssl.py", line 1104, in read
    return self._sslobj.read(len, buffer)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TimeoutError: The read operation timed out

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.12/site-packages/requests/adapters.py", line 486, in send
    resp = conn.urlopen(
           ^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 799, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/util/retry.py", line 550, in increment
    raise six.reraise(type(error), error, _stacktrace)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/packages/six.py", line 770, in reraise
    raise value
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 715, in urlopen
    httplib_response = self._make_request(
                       ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 469, in _make_request
    self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
  File "/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py", line 358, in _raise_timeout
    raise ReadTimeoutError(
urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='api.spotify.com', port=443): Read timed out. (read timeout=5)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/config/custom_components/spotcast/helpers.py", line 102, in run
    return await loop.run_in_executor(executor, pfunc)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/spotcast/__init__.py", line 141, in get_devices
    resp = get_spotify_devices(spotify_media_player)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/spotcast/helpers.py", line 58, in get_spotify_devices
    spotify_devices = spotify_media_player.data.client.devices()
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/spotipy/client.py", line 1748, in devices
    return self._get("me/player/devices")
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/spotipy/client.py", line 323, in _get
    return self._internal_call("GET", url, payload, kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/spotipy/client.py", line 266, in _internal_call
    response = self._session.request(
               ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/requests/adapters.py", line 532, in send
    raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='api.spotify.com', port=443): Read timed out. (read timeout=5)
fcusson commented 1 month ago

Simple question: Could this be "only" related to when HAOS (warm or cold) restart? And if so, would it be possible to add say a delay when started to make sure whatever is needed to be available is just available?

Background on this is from my own sensor for light which is setup in configuration.yaml, where I have to add a minor thing to get it stable without any (re-)start errors in the log: states('sensor.light_home') in ['unavailable', 'unknown', 'none']

No this is handled by Home Assistant for integration. We list our dependencies and the integration isn't loaded until the first one is correctly loaded. If it doesn't load, it will not become available.

Also configuration is always loaded, integration can't start to load before the configuration itself is loaded.

The timeout errors you are receiving are poiting to much deeper problem in you setup. This is indicative of network problem on your end or spotify end. Do you have anything on yourt network that might cause connection error like a pihole or something of the kind?

Also I finally had time to look at the code properly. This error will only arrise if you call spotcast with a specific account. Can you test what happens when you call without an account first? Also please provide a copy of the service call you made to get the original error.

larhedse commented 1 month ago

Well then I guess we can close this:

a) The first one, the original issue, seems to be inside HA (as usual) so nothing to do about it. I can live with that. b) Yes, running DNS and Country block - yes that will f*ck up CDNs and stuff. I can live with that too.

larhedse commented 1 month ago

Oh by the way: to your last question: If I change account I get more errors - lets not go into that then. It will just be the same.