8000 Better Integration Error Messages by Waidhoferj · Pull Request #46 · y-crdt/ypy · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

Better Integration Error Messages #46

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion src/shared_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
y_xml::{YXmlElement, YXmlText},
};
use pyo3::prelude::*;
use std::convert::TryFrom;
use std::{convert::TryFrom, fmt::Display};
use yrs::types::TYPE_REFS_XML_ELEMENT;
use yrs::types::TYPE_REFS_XML_TEXT;
use yrs::types::{TypeRefs, TYPE_REFS_ARRAY, TYPE_REFS_MAP, TYPE_REFS_TEXT};
Expand Down Expand Up @@ -37,6 +37,19 @@ pub enum Shared {
XmlText(Py<YXmlText>),
}

impl Display for Shared {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let str_repr = Python::with_gil(|py| match &self {
Shared::Text(text) => text.borrow(py).__str__(),
Shared::Array(arr) => arr.borrow(py).__str__(),
Shared::Map(map) => map.borrow(py).__str__(),
Shared::XmlElement(xml_el) => xml_el.borrow(py).__str__(),
Shared::XmlText(xml_text) => xml_text.borrow(py).__str__(),
});
write!(f, "{}", str_repr)
}
}

impl Shared {
pub fn is_prelim(&self) -> bool {
Python::with_gil(|py| match self {
Expand Down
80 changes: 55 additions & 25 deletions src/type_conversions.rs
8000
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use lib0::any::Any;
use pyo3::create_exception;
use pyo3::exceptions::PyException;
use pyo3::exceptions::PyTypeError;
use pyo3::prelude::*;
use pyo3::types as pytypes;

use std::collections::HashMap;
use std::convert::TryFrom;
use std::ops::Deref;
Expand All @@ -14,6 +18,8 @@ use crate::y_map::YMap;
use crate::y_text::YText;
use crate::y_xml::{YXmlElement, YXmlText};

create_exception!(y_py, MultipleIntegrationError, PyException);

pub trait ToPython {
fn into_py(self, py: Python) -> PyObject;
}
Expand Down Expand Up @@ -137,28 +143,38 @@ struct PyObjectWrapper(PyObject);

impl Prelim for PyObjectWrapper {
fn into_content(self, _txn: &mut Transaction) -> (ItemContent, Option<Self>) {
let guard = Python::acquire_gil();
let py = guard.python();
let content = if let Some(any) = py_into_any(self.0.clone()) {
ItemContent::Any(vec![any])
} else if let Ok(shared) = Shared::extract(self.0.as_ref(py)) {
if shared.is_prelim() {
let branch = Branch::new(shared.type_ref(), None);
ItemContent::Type(branch)
Python::with_gil(|py| {
let content = if let Some(any) = py_into_any(self.0.clone()) {
ItemContent::Any(vec![any])
} else if let Ok(shared) = Shared::extract(self.0.as_ref(py)) {
if shared.is_prelim() {
let branch = Branch::new(shared.type_ref(), None);
ItemContent::Type(branch)
} else {
let error_message = format!(
"Cannot integrate data that is already a part of another YDoc: {shared}"
);
let type_error = MultipleIntegrationError::new_err(error_message);
type_error.restore(py);
panic!();
}
} else {
panic!("Cannot integrate this type")
}
} else {
panic!("Cannot integrate this type")
};
let unknown_type = self.0;
let error_message =
format!("Cannot integrate this Python type into a YDoc: {unknown_type}");
let type_error = PyTypeError::new_err(error_message);
type_error.restore(py);
panic!();
};

let this = if let ItemContent::Type(_) = &content {
Some(self)
} else {
None
};
let this = if let ItemContent::Type(_) = &content {
Some(self)
} else {
None
};

(content, this)
(content, this)
})
}

fn integrate(self, txn: &mut Transaction, inner_ref: BranchPtr) {
Expand All @@ -167,7 +183,8 @@ impl Prelim for PyObjectWrapper {
let obj_ref = self.0.as_ref(py);
if let Ok(shared) = Shared::extract(obj_ref) {
if shared.is_prelim() {
Python::with_gil(|py| match shared {
Python::with_gil(|py| {
match shared {
Shared::Text(v) => {
let text = Text::from(inner_ref);
let mut y_text = v.borrow_mut(py);
Expand Down Expand Up @@ -196,7 +213,8 @@ impl Prelim for PyObjectWrapper {
}
y_map.0 = SharedType::Integrated(map.clone());
}
_ => panic!("Cannot integrate this type"),
Shared::XmlElement(_) | Shared::XmlText(_) => unreachable!("As defined in Shared::is_prelim(), neither XML type can ever exist outside a YDoc"),
}
})
}
}
Expand Down Expand Up @@ -335,10 +353,20 @@ impl Prelim for PyValueWrapper {
let branch = Branch::new(shared.type_ref(), None);
ItemContent::Type(branch)
} else {
panic!("Cannot integrate this type")
let error_message = format!(
"Cannot integrate data that is already a part of another YDoc: {shared}"
);
let type_error = MultipleIntegrationError::new_err(error_message);
Python::with_gil(|py| type_error.restore(py));
ItemContent::Any(Vec::new())
}
} else {
panic!("Cannot integrate this type")
let unknown_type = self.0;
let error_message =
format!("Cannot integrate this Python type into a YDoc: {unknown_type}");
let type_error = PyTypeError::new_err(error_message);
Python::with_gil(|py| type_error.restore(py));
panic!();
};

let this = if let ItemContent::Type(_) = &content {
Expand All @@ -353,7 +381,8 @@ impl Prelim for PyValueWrapper {
fn integrate(self, txn: &mut Transaction, inner_ref: BranchPtr) {
if let Ok(shared) = Shared::try_from(self.0) {
if shared.is_prelim() {
Python::with_gil(|py| match shared {
Python::with_gil(|py| {
match shared {
Shared::Text(v) => {
let text = Text::from(inner_ref);
let mut y_text = v.borrow_mut(py);
Expand Down Expand Up @@ -383,7 +412,8 @@ impl Prelim for PyValueWrapper {
}
y_map.0 = SharedType::Integrated(map.clone());
}
_ => panic!("Cannot integrate this type"),
Shared::XmlElement(_) | Shared::XmlText(_) => unreachable!("As defined in Shared::is_prelim(), neither XML type can ever exist outside a YDoc"),
}
})
}
}
Expand Down
0