Browse Source

wip: play with error code

Jonathan Kelley 2 năm trước cách đây
mục cha
commit
62d672fc90

+ 1 - 1
packages/core/src/lib.rs

@@ -34,7 +34,7 @@ pub(crate) mod innerlude {
     /// An [`Element`] is a possibly-errored [`VNode`] created by calling `render` on [`Scope`] or [`ScopeState`].
     ///
     /// An Errored [`Element`] will propagate the error to the nearest error boundary.
-    pub type Element<'a> = anyhow::Result<VNode<'a>>;
+    pub type Element<'a> = Result<VNode<'a>, anyhow::Error>;
 
     /// A [`Component`] is a function that takes a [`Scope`] and returns an [`Element`].
     ///

+ 69 - 0
packages/core/tests/bubble_error.rs

@@ -1 +1,70 @@
+//! we should properly bubble up errors from components
 
+use std::{error::Error as StdError, marker::PhantomData, string::ParseError};
+
+use anyhow::{anyhow, bail};
+use dioxus::prelude::*;
+
+// todo: add these to dioxus
+pub trait Reject<E: Clone>: Sized {
+    fn reject_err(self, t: impl FnOnce(E) -> anyhow::Error) -> Result<Self, anyhow::Error> {
+        todo!()
+    }
+    fn reject_because(self, t: impl Into<String>) -> Result<Self, anyhow::Error> {
+        todo!()
+    }
+
+    fn reject(self) -> Result<Self, anyhow::Error> {
+        todo!()
+    }
+}
+
+impl<T, E: Clone> Reject<E> for &Result<T, E> {
+    fn reject_err(self, t: impl FnOnce(E) -> anyhow::Error) -> Result<Self, anyhow::Error> {
+        todo!()
+    }
+}
+
+fn use_query_param<'a>(cx: &'a ScopeState) -> Result<&'a i32, ParseError> {
+    todo!()
+}
+
+/// Call "clone" on the underlying error so it can be propogated out
+pub trait CloneErr<T, E: ToOwned> {
+    fn clone_err(&self) -> Result<&T, E::Owned>
+    where
+        Self: Sized;
+}
+
+impl<E: ToOwned, T> CloneErr<T, E> for Result<T, E> {
+    fn clone_err(&self) -> Result<&T, E::Owned>
+    where
+        Self: Sized,
+    {
+        match self {
+            Ok(s) => Ok(s),
+            Err(e) => Err(e.to_owned()),
+        }
+    }
+}
+
+fn app(cx: Scope) -> Element {
+    // propgates error upwards, does not give a reason, lets Dioxus figure it out
+    let value = cx.use_hook(|| "123123123.123".parse::<f32>()).reject()?;
+
+    // propgates error upwards, gives a reason
+    let value = cx
+        .use_hook(|| "123123123.123".parse::<f32>())
+        .reject_because("Parsing float failed")?;
+
+    let value = cx.use_hook(|| "123123123.123".parse::<f32>()).clone_err()?;
+
+    let t = use_query_param(cx)?;
+
+    let value = cx
+        .use_hook(|| "123123123.123".parse::<f32>())
+        .as_ref()
+        .map_err(|_| anyhow!("Parsing float failed"))?;
+
+    todo!()
+}

+ 0 - 0
packages/core/tests/fragments.rs → packages/core/tests/create_fragments.rs


+ 23 - 0
packages/core/tests/lists.rs → packages/core/tests/create_lists.rs

@@ -25,6 +25,29 @@ fn list_renders() {
 
     let edits = dom.rebuild().santize();
 
+    assert_eq!(
+        edits.template_mutations,
+        [
+            // Create the outer div
+            CreateElement { name: "div", namespace: None, id: ElementId(1) },
+            // todo: since this is the only child, we should just use
+            // append when modify the values (IE no need for a placeholder)
+            CreatePlaceholder { id: ElementId(2) },
+            AppendChildren { m: 1 },
+            SaveTemplate { name: "template", m: 1 },
+            // Create the inner template div
+            CreateElement { name: "div", namespace: None, id: ElementId(3) },
+            CreateElement { name: "h1", namespace: None, id: ElementId(4) },
+            CreateStaticText { value: "hello world! " },
+            AppendChildren { m: 1 },
+            CreateElement { name: "p", namespace: None, id: ElementId(5) },
+            CreateStaticText { value: "d" },
+            AppendChildren { m: 1 },
+            AppendChildren { m: 2 },
+            SaveTemplate { name: "template", m: 1 }
+        ]
+    );
+
     assert_eq!(
         edits.edits,
         [

+ 0 - 0
packages/core/tests/passthru.rs → packages/core/tests/create_passthru.rs