Bubble errors from the server to the client on suspense boundaries (#2772)
* Bubble errors from the server to the client on suspense boundaries * make resolving suspense boundaries O(n)
This commit is contained in:
1 parent
3003362b52
commit
b0a2e2418c
12 files changed
+190
-39
No files matched your search
@@ -40,13 +40,11 @@ impl Display for CapturedPanic {
|
||||
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_or_else(|e| panic!("{}", e)),
|
||||
))
|
||||
})
|
||||
pub fn provide_error_boundary() -> ErrorContext {
|
||||
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.
|
||||
@@ -750,7 +748,7 @@ impl<
|
||||
/// Error boundaries are quick to implement, but it can be useful to individually handle errors in your components to provide a better user experience when you know that an error is likely to occur.
|
||||
#[allow(non_upper_case_globals, non_snake_case)]
|
||||
pub fn ErrorBoundary(props: ErrorBoundaryProps) -> Element {
|
||||
let error_boundary = use_error_boundary();
|
||||
let error_boundary = use_hook(provide_error_boundary);
|
||||
let errors = error_boundary.errors();
|
||||
if errors.is_empty() {
|
||||
std::result::Result::Ok({
|
||||
@@ -768,6 +766,8 @@ pub fn ErrorBoundary(props: ErrorBoundaryProps) -> Element {
|
||||
)
|
||||
})
|
||||
} else {
|
||||
tracing::trace!("scope id: {:?}", current_scope_id());
|
||||
tracing::trace!("handling errors: {:?}", errors);
|
||||
(props.handle_error.0)(error_boundary.clone())
|
||||
}
|
||||
}
|
||||
@@ -88,10 +88,10 @@ pub mod prelude {
|
||||
pub use crate::innerlude::{
|
||||
consume_context, consume_context_from_scope, current_owner, current_scope_id,
|
||||
fc_to_builder, generation, has_context, needs_update, needs_update_any, parent_scope,
|
||||
provide_context, provide_root_context, queue_effect, remove_future, schedule_update,
|
||||
schedule_update_any, spawn, spawn_forever, spawn_isomorphic, suspend, throw_error,
|
||||
try_consume_context, use_after_render, use_before_render, use_drop, use_error_boundary,
|
||||
use_hook, use_hook_with_cleanup, with_owner, AnyValue, Attribute, Callback, Component,
|
||||
provide_context, provide_error_boundary, provide_root_context, queue_effect, remove_future,
|
||||
schedule_update, schedule_update_any, spawn, spawn_forever, spawn_isomorphic, suspend,
|
||||
throw_error, try_consume_context, use_after_render, use_before_render, use_drop, use_hook,
|
||||
use_hook_with_cleanup, with_owner, AnyValue, Attribute, Callback, Component,
|
||||
ComponentFunction, Context, Element, ErrorBoundary, ErrorContext, Event, EventHandler,
|
||||
Fragment, HasAttributes, IntoAttributeValue, IntoDynNode, OptionStringFromMarker,
|
||||
Properties, ReactiveContext, RenderError, RenderReturn, Runtime, RuntimeGuard, ScopeId,
|
||||
|
||||
@@ -190,10 +190,10 @@ impl Scope {
|
||||
/// Clones the state if it exists.
|
||||
pub fn consume_context<T: 'static + Clone>(&self) -> Option<T> {
|
||||
tracing::trace!(
|
||||
"looking for context {} ({:?}) in {}",
|
||||
"looking for context {} ({:?}) in {:?}",
|
||||
std::any::type_name::<T>(),
|
||||
std::any::TypeId::of::<T>(),
|
||||
self.name
|
||||
self.id
|
||||
);
|
||||
if let Some(this_ctx) = self.has_context() {
|
||||
return Some(this_ctx);
|
||||
@@ -207,10 +207,10 @@ impl Scope {
|
||||
return None;
|
||||
};
|
||||
tracing::trace!(
|
||||
"looking for context {} ({:?}) in {}",
|
||||
"looking for context {} ({:?}) in {:?}",
|
||||
std::any::type_name::<T>(),
|
||||
std::any::TypeId::of::<T>(),
|
||||
parent.name
|
||||
parent.id
|
||||
);
|
||||
if let Some(shared) = parent.has_context() {
|
||||
return Some(shared);
|
||||
@@ -277,10 +277,10 @@ impl Scope {
|
||||
/// ```
|
||||
pub fn provide_context<T: 'static + Clone>(&self, value: T) -> T {
|
||||
tracing::trace!(
|
||||
"providing context {} ({:?}) in {}",
|
||||
"providing context {} ({:?}) in {:?}",
|
||||
std::any::type_name::<T>(),
|
||||
std::any::TypeId::of::<T>(),
|
||||
self.name
|
||||
self.id
|
||||
);
|
||||
let mut contexts = self.shared_contexts.borrow_mut();
|
||||
|
||||
|
||||
Reference in new issue
Block a user