y-crdt/ypy

Turn rust errors into exceptions

ksamuel opened this issue · 2 comments

There are bugs we cannot report because the underlying error is not reported. E.G:

import y_py as Y

d1 = Y.YDoc()
root = d1.get_map('stuff')
sub = d1.get_map('sub')

with d1.begin_transaction() as txn:
    root.set(txn, "foo", "bar")
    sub.set(txn, "a", "b")
    root.set(txn, "sub", sub)

Will raise "SystemError: <method 'set' of 'builtins.YMap' objects> returned a result with an error set", so I have no way to know what happens and create a minimal working example out of it.

I see what you mean about the final error message. Running the example above, I get the following:

y_py.MultipleIntegrationError: Cannot integrate a nested Ypy object because is already integrated into a YDoc: {'a': 'b'}

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
SystemError: <method 'set' of 'builtins.YMap' objects> returned a result with an error set

The first error is thrown further down the call stack and causes the second at the set method. This is expected behavior.

Let me know if the first error message is not visible for some reason, and I can look into it

To elaborate on the example you provided, the final set should throw an error since it is attempting to create a parent/child relationship between 2 siblings already integrated into the CRDT. If we allowed this, you could create cycles inside the CRDT which would cause all sorts of issues. If you want to add the contents of an already integrated YMap as a child of another YMap, you can turn the map back into a python dict using to_json():

d1 = Y.YDoc()
root = d1.get_map("stuff")
sub = d1.get_map("sub")

with d1.begin_transaction() as txn:
    root.set(txn, "foo", "bar")
    sub.set(txn, "a", "b")
    sub = sub.to_json()
    root.set(txn, "sub", sub)