Skip to content

get_tree() crashes with a JSON decode error #175

Closed

Description

@wonkalous

I have been experimenting with one of your examples and I keep getting a JSON decode error triggered by a call to aio.Con.get_tree(). Here is a paired down snippet that triggers the issue:

#!/usr/bin/env python3

import asyncio
import logging
from i3ipc.aio import Connection

SOCKET_FILE = '/tmp/.i3-cycle-focus.sock'

class FocusWatcher:
    def __init__(self):
        self.i3 = None

    async def connect(self):
        self.i3 = await Connection().connect()
        self.i3.on('window::focus', self.on_window_focus)

    async def on_window_focus(self, i3conn, event):
        logging.info('got window focus event')
        tree = await self.i3.get_tree()

    async def run(self):
        async def handle_switch(reader, writer):
            data = await reader.read(1024)
            logging.info('received data: {}').format(data)

        server = await asyncio.start_unix_server(handle_switch, SOCKET_FILE)
        await server.serve_forever()

async def run_server():
    focus_watcher = FocusWatcher()
    await focus_watcher.connect()
    await focus_watcher.run()


if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    asyncio.run(run_server())

here is an example log output:

... (normal looking long json representing the tree)...
x":0,"y":0,"width":0,"height":0},"geometry":{"x":0,"y":0,"width":0,"height":0},"name":"25","num":25,"window":null,"window_type":null,"nodes":[{"id":94793549'
INFO:i3ipc.aio.connection:quitting the main loop
Traceback (most recent call last):
  File "/home/epenn/code/i3ipc-python/.env/lib/python3.8/site-packages/i3ipc-2.2.1-py3.8.egg/i3ipc/aio/connection.py", line 37, in handler_coroutine
    await handler(conn, data)
  File "examples/bug.py", line 27, in on_window_focus
    tree = await self.i3.get_tree()
  File "/home/epenn/code/i3ipc-python/.env/lib/python3.8/site-packages/i3ipc-2.2.1-py3.8.egg/i3ipc/aio/connection.py", line 628, in get_tree
    return Con(json.loads(data), None, self)
  File "/usr/lib/python3.8/json/__init__.py", line 357, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python3.8/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python3.8/json/decoder.py", line 353, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 1 column 36519 (char 36518)

As you can see, the json message is truncated, causing a decode error. To reproduce this behavior, it is necessary to run the script and then change focus (triggering the get_tree call). It will take sometimes ~5 focus events to trigger, other times hundreds.

Activity

  1. acrisci commented on Feb 12, 2021

    @acrisci
    Member

    I think I would need to add some logging to investigate this.

  2. jvasile commented on Mar 15, 2021

    @jvasile

    I'm hitting this error when I get_tree() as well. What is interesting to me is that I get the json error at the same place: line 1, column 36519. The JSON string is getting truncated somewhere.

    Relevant part of the stacktrace:

    Traceback (most recent call last):
    File "/home/james/src/floating-tiles/./ft-alt-tab.py", line 284, in <module>
    asyncio.run(main())
    File "/usr/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
    File "/usr/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
    File "/home/james/src/floating-tiles/./ft-alt-tab.py", line 263, in main
    await asyncio.gather(*listeners)
    File "/home/james/src/floating-tiles/./ft-alt-tab.py", line 250, in i3ipc_main
    await i3.main()
    File "/home/james/.local/lib/python3.9/site-packages/i3ipc/aio/connection.py", line 664, in main
    await self._main_future
    File "/home/james/.local/lib/python3.9/site-packages/i3ipc/aio/connection.py", line 34, in handler_coroutine
    await handler(conn, data)
    File "/home/james/src/floating-tiles/./ft-alt-tab.py", line 123, in record_focus_change_unless_active
    await self.record_focus_change(i3)
    File "/home/james/src/floating-tiles/./ft-alt-tab.py", line 104, in record_focus_change
    tree = await conn.get_tree()
    File "/home/james/.local/lib/python3.9/site-packages/i3ipc/aio/connection.py", line 589, in get_tree
    return Con(json.loads(data), None, self)
    File "/usr/lib/python3.9/json/__init__.py", line 346, in loads
    return _default_decoder.decode(s)
    File "/usr/lib/python3.9/json/decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    File "/usr/lib/python3.9/json/decoder.py", line 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
    json.decoder.JSONDecodeError: Expecting value: line 1 column 36519 (char 36518)
    
  3. jvasile commented on Mar 15, 2021

    @jvasile

    This appears to avoid the error:

        try:
            tree = await conn.get_tree()
        except json.decoder.JSONDecodeError:
            # We're doing this in a non-async way because the async connection
            # above was throwing JSON decode errors (see
            # https://github.com/altdesktop/i3ipc-python/issues/175)
            i3 = i3ipc.Connection()
            tree = i3.get_tree()
    
  4. haolian9 commented on Jul 1, 2021

    @haolian9

    can anybody got this decode error provide a complete raw json responsed by i3wm/sway? using the following codes

    data = conn._message(MessageType.GET_TREE, '')
    print(data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions