فهرست منبع

Follow-up for error messages in core (#2719)

* Fix tests

* Replace unwraps on RuntimeError with panics and add track_caller for better error output

* Convert more unwraps

* Fix git
Matt Hunzinger 11 ماه پیش
والد
کامیت
6558fd95a2

+ 6 - 1
packages/core/src/error_boundary.rs

@@ -41,7 +41,12 @@ impl Error for CapturedPanic {}
 
 /// Provide an error boundary to catch errors from child components
 pub fn use_error_boundary() -> ErrorContext {
-    use_hook(|| provide_context(ErrorContext::new(Vec::new(), current_scope_id().unwrap())))
+    use_hook(|| {
+        provide_context(ErrorContext::new(
+            Vec::new(),
+            current_scope_id().unwrap_or_else(|e| panic!("{}", e)),
+        ))
+    })
 }
 
 /// A trait for any type that can be downcast to a concrete type and implements Debug. This is automatically implemented for all types that implement Any + Debug.

+ 4 - 3
packages/core/src/events.rs

@@ -397,7 +397,7 @@ impl<Args: 'static, Ret: 'static> Callback<Args, Ret> {
         ));
         Self {
             callback,
-            origin: current_scope_id().unwrap(),
+            origin: current_scope_id().unwrap_or_else(|e| panic!("{}", e)),
         }
     }
 
@@ -409,13 +409,14 @@ impl<Args: 'static, Ret: 'static> Callback<Args, Ret> {
                 as Rc<RefCell<dyn FnMut(Args) -> Ret>>));
         Self {
             callback,
-            origin: current_scope_id().unwrap(),
+            origin: current_scope_id().unwrap_or_else(|e| panic!("{}", e)),
         }
     }
 
     /// Call this callback with the appropriate argument type
     ///
     /// This borrows the callback using a RefCell. Recursively calling a callback will cause a panic.
+    #[track_caller]
     pub fn call(&self, arguments: Args) -> Ret {
         if let Some(callback) = self.callback.read().as_ref() {
             Runtime::with(|rt| {
@@ -427,7 +428,7 @@ impl<Args: 'static, Ret: 'static> Callback<Args, Ret> {
                     value
                 })
             })
-            .unwrap()
+            .unwrap_or_else(|e| panic!("{}", e))
         } else {
             panic!("Callback was manually dropped")
         }

+ 2 - 1
packages/core/src/generational_box.rs

@@ -90,7 +90,8 @@ pub fn current_owner<S: AnyStorage>() -> Owner<S> {
 
 impl ScopeId {
     /// Get the owner for the current scope.
+    #[track_caller]
     pub fn owner<S: AnyStorage>(self) -> Owner<S> {
-        Runtime::with_scope(self, |cx| cx.owner::<S>()).unwrap()
+        Runtime::with_scope(self, |cx| cx.owner::<S>()).unwrap_or_else(|e| panic!("{}", e))
     }
 }

+ 7 - 3
packages/core/src/global_context.rs

@@ -35,7 +35,9 @@ pub fn vdom_is_rendering() -> bool {
 /// }
 /// ```
 pub fn throw_error(error: impl Into<CapturedError> + 'static) {
-    current_scope_id().unwrap().throw_error(error)
+    current_scope_id()
+        .unwrap_or_else(|e| panic!("{}", e))
+        .throw_error(error)
 }
 
 /// Consume context from the current scope
@@ -289,8 +291,9 @@ pub fn needs_update_any(id: ScopeId) {
 /// Note: Unlike [`needs_update`], the function returned by this method will work outside of the dioxus runtime.
 ///
 /// You should prefer [`schedule_update_any`] if you need to update multiple components.
+#[track_caller]
 pub fn schedule_update() -> Arc<dyn Fn() + Send + Sync> {
-    Runtime::with_current_scope(|cx| cx.schedule_update()).unwrap()
+    Runtime::with_current_scope(|cx| cx.schedule_update()).unwrap_or_else(|e| panic!("{}", e))
 }
 
 /// Schedule an update for any component given its [`ScopeId`].
@@ -298,8 +301,9 @@ pub fn schedule_update() -> Arc<dyn Fn() + Send + Sync> {
 /// A component's [`ScopeId`] can be obtained from the [`current_scope_id`] method.
 ///
 /// Note: Unlike [`needs_update`], the function returned by this method will work outside of the dioxus runtime.
+#[track_caller]
 pub fn schedule_update_any() -> Arc<dyn Fn(ScopeId) + Send + Sync> {
-    Runtime::with_current_scope(|cx| cx.schedule_update_any()).unwrap()
+    Runtime::with_current_scope(|cx| cx.schedule_update_any()).unwrap_or_else(|e| panic!("{}", e))
 }
 
 /// Creates a callback that will be run before the component is removed.

+ 5 - 1
packages/core/src/reactive_context.rs

@@ -67,7 +67,11 @@ impl ReactiveContext {
             }
             let _ = tx.unbounded_send(());
         };
-        let _self = Self::new_with_callback(callback, current_scope_id().unwrap(), origin);
+        let _self = Self::new_with_callback(
+            callback,
+            current_scope_id().unwrap_or_else(|e| panic!("{}", e)),
+            origin,
+        );
         (_self, rx)
     }
 

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

@@ -50,7 +50,7 @@ impl VirtualDom {
     #[track_caller]
     pub(crate) fn run_scope(&mut self, scope_id: ScopeId) -> RenderReturn {
         // Ensure we are currently inside a `Runtime`.
-        crate::Runtime::current().unwrap();
+        crate::Runtime::current().unwrap_or_else(|e| panic!("{}", e));
 
         self.runtime.clone().with_scope_on_stack(scope_id, || {
             let scope = &self.scopes[scope_id.0];

+ 4 - 2
packages/core/src/scope_context.rs

@@ -97,7 +97,7 @@ impl Scope {
     }
 
     fn sender(&self) -> futures_channel::mpsc::UnboundedSender<SchedulerMsg> {
-        Runtime::with(|rt| rt.sender.clone()).unwrap()
+        Runtime::with(|rt| rt.sender.clone()).unwrap_or_else(|e| panic!("{}", e))
     }
 
     /// Mount the scope and queue any pending effects if it is not already mounted
@@ -531,7 +531,9 @@ impl ScopeId {
     /// Run a closure inside of scope's runtime
     #[track_caller]
     pub fn in_runtime<T>(self, f: impl FnOnce() -> T) -> T {
-        Runtime::current().unwrap().on_scope(self, f)
+        Runtime::current()
+            .unwrap_or_else(|e| panic!("{}", e))
+            .on_scope(self, f)
     }
 
     /// Throw a [`CapturedError`] into a scope. The error will bubble up to the nearest [`ErrorBoundary`] or the root of the app.

+ 1 - 1
packages/core/src/suspense/mod.rs

@@ -46,7 +46,7 @@ impl SuspendedFuture {
     pub fn new(task: Task) -> Self {
         Self {
             task,
-            origin: current_scope_id().unwrap(),
+            origin: current_scope_id().unwrap_or_else(|e| panic!("{}", e)),
             placeholder: VNode::placeholder(),
         }
     }

+ 9 - 4
packages/core/src/tasks.rs

@@ -7,6 +7,7 @@ use crate::ScopeId;
 use futures_util::task::ArcWake;
 use slotmap::DefaultKey;
 use std::marker::PhantomData;
+use std::panic;
 use std::sync::Arc;
 use std::task::Waker;
 use std::{cell::Cell, future::Future};
@@ -76,21 +77,24 @@ impl Task {
     }
 
     /// Wake the task.
+    #[track_caller]
     pub fn wake(&self) {
         Runtime::with(|rt| {
             _ = rt
                 .sender
                 .unbounded_send(SchedulerMsg::TaskNotified(self.id))
         })
-        .unwrap();
+        .unwrap_or_else(|e| panic!("{}", e))
     }
 
     /// Poll the task immediately.
+    #[track_caller]
     pub fn poll_now(&self) -> Poll<()> {
-        Runtime::with(|rt| rt.handle_task_wakeup(*self)).unwrap()
+        Runtime::with(|rt| rt.handle_task_wakeup(*self)).unwrap_or_else(|e| panic!("{}", e))
     }
 
     /// Set the task as active or paused.
+    #[track_caller]
     pub fn set_active(&self, active: bool) {
         Runtime::with(|rt| {
             if let Some(task) = rt.tasks.borrow().get(self.id) {
@@ -102,7 +106,7 @@ impl Task {
                 }
             }
         })
-        .unwrap();
+        .unwrap_or_else(|e| panic!("{}", e))
     }
 }
 
@@ -247,11 +251,12 @@ impl Runtime {
         self.tasks.borrow().get(task.id).map(|t| t.scope)
     }
 
+    #[track_caller]
     pub(crate) fn handle_task_wakeup(&self, id: Task) -> Poll<()> {
         #[cfg(debug_assertions)]
         {
             // Ensure we are currently inside a `Runtime`.
-            Runtime::current().unwrap();
+            Runtime::current().unwrap_or_else(|e| panic!("{}", e));
         }
 
         let task = self.tasks.borrow().get(id.id).cloned();