feat(post_detail): propagate NotFound and other load errors to ErrorBoundary

This commit is contained in:
xfy 2026-07-09 17:31:49 +08:00
parent 37e8f51fac
commit 1b38162ca4

View File

@ -20,7 +20,6 @@
//! 实际的数据库访问逻辑仅在 `feature = "server"` 启用时运行。
use dioxus::prelude::*;
use dioxus::router::components::Link;
use crate::api::posts::{get_post_by_slug, SinglePostResponse};
use crate::components::post::post_content::PostContent;
@ -55,15 +54,30 @@ pub fn PostDetail(slug: String) -> Element {
get_post_by_slug(current_slug)
})?;
// 将结果映射为更直观的 Ok(post) / Err("not_found") / Err("error") 三种状态。
// 将结果映射为 Ok(post) 或 Err(ServerFnError) 用于错误边界捕获
let post_data = post.read().as_ref().map(|r| match r {
Ok(SinglePostResponse { post: Some(post) }) => Ok(post.clone()),
Ok(SinglePostResponse { post: None }) => Err("not_found"),
Err(_) => Err("error"),
Ok(SinglePostResponse { post: None }) => Err(ServerFnError::ServerError {
message: "not_found".to_string(),
code: 404,
details: None,
}),
Err(e) => Err(e.clone()),
});
match post_data {
Some(Ok(post)) => {
let post = match post_data {
Some(Ok(post)) => post,
Some(Err(err)) => {
// Bubble the error up to the ErrorBoundary
return Err(err.into());
}
None => {
return rsx! {
DelayedSkeleton { PostDetailSkeleton {} }
};
}
};
rsx! {
article { class: "post-single animate-page-enter", key: "{post.slug}",
PostHeader { post: post.clone() }
@ -117,31 +131,4 @@ pub fn PostDetail(slug: String) -> Element {
}
}
}
}
Some(Err("not_found")) => {
rsx! {
div { class: "text-center py-20",
h2 { class: "text-2xl font-bold text-paper-primary mb-4", "文章不存在" }
p { class: "text-paper-secondary mb-6",
"这篇文章可能已被删除或移动。"
}
Link {
class: "px-6 py-2 bg-paper-primary text-paper-theme rounded-full font-medium hover:opacity-80 transition-opacity",
to: Route::Home {},
"返回首页"
}
}
}
}
Some(Err("error")) => {
rsx! {
div { class: "text-center text-red-500 dark:text-red-400 py-20", "加载失败" }
}
}
_ => {
rsx! {
DelayedSkeleton { PostDetailSkeleton {} }
}
}
}
}