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
This commit is contained in:
Matt Hunzinger 2024-07-29 16:15:06 -04:00 committed by GitHub
parent a1dfc4b4f0
commit 6558fd95a2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 39 additions and 17 deletions

View file

@ -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.

View file

@ -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")
}

View file

@ -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))
}
}

View file

@ -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.

View file

@ -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)
}

View file

@ -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];

View file

@ -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.

View file

@ -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(),
}
}

View file

@ -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();