pythonjsonrosrospy

Rospy JSONDecodeError when loading from file with json.load()


I'm trying to store the data published on a topic to a JSON file, but I keep getting a JSONDecodeError.

    DB = '/home/path/data.json'
    f = open(DB, 'w+')

    json_array = json.load(fp=f)

    json_array.append(data)
    json.dump(json_array, f)
    f.close()

The open() command successfully creates the file. But loading fails. I have tried running it with the file contents: [] and {}, both gave the same Exception:

[ERROR] [1637699609.562673]: bad callback: <function callback at 0x7fe36196b1f0>
Traceback (most recent call last):
  File "/opt/ros/noetic/lib/python3/dist-packages/rospy/topics.py", line 750, in _invoke_callback
    cb(msg)
  File "/home/path/scripts/extract_info_node.py", line 43, in callback
    json_array = json.load(fp=f)
  File "/usr/lib/python3.8/json/__init__.py", line 293, in load
    return loads(fp.read(),
  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 355, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

It's not really descriptive and I have nothing to go on. Is there something about the way subscribers are run that doesn't allow writing? Can you even do this from a callback function? I have just started working in ROS so it could be something simple or obvious to someone more experienced.


Solution

  • .load() takes a .read() supporting file. You're only opening the file for reading. Instead try this:

    f = open(DB, 'r+')
    
    json_array = json.load(f)
    

    As another note, if you're storing and re-reading topic data I'd suggest looking potentially using rosbag. This is, however, dependent on your actual application.