Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

process_markdown_to_html causes tokio-runtime-worker to panic #1

Open
khanhtimn opened this issue Nov 18, 2024 · 0 comments
Open

process_markdown_to_html causes tokio-runtime-worker to panic #1

khanhtimn opened this issue Nov 18, 2024 · 0 comments

Comments

@khanhtimn
Copy link

Describe the bug
I am using femark to render html in my leptos blog. femark::process_markdown_to_html causes tokio-runtime-worker to panic IF there are code block(s) in the input. I'm sorry if it's inappropriate to open an issue here but I have been looking at your leptos blog for reference and this issue seems specific enough, sorry for any inconvenience.

Leptos Dependencies

leptos = { version = "0.7.0-rc1", features = ["nightly"] }
leptos_meta = { version = "0.7.0-rc1" }
leptos_router = { version = "0.7.0-rc1" }
leptos_axum = { version = "0.7.0-rc1" }
axum = { version = "0.7", features = ["macros"] }
femark = "0.1.6"
sqlx = { version = "0.8", features = [
    "runtime-tokio-rustls",
    "macros",
    "postgres",
    "chrono",
] }

To Reproduce

  • Struct definitions:
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct BlogPost {
    pub id: i64,
    pub title: String,
    pub description: String,
    pub hero_image: String,
    pub content: String,
    pub published_at: String,
    pub slug: String,
    #[serde(skip_serializing_if = "Vec::is_empty")]
    pub categories: Vec<Category>,
}

cfg_if! {
    if #[cfg(feature = "ssr")] {
        use femark::HTMLOutput;
        use chrono::{DateTime, Local};

        #[derive(sqlx::FromRow, sqlx::Type)]
        pub struct SqlPost{
            pub id: i64,
            pub title: String,
            pub description: String,
            pub hero_image: String,
            pub content: String,
            pub published_at: DateTime<Local>,
            pub slug: String,
            pub categories: Vec<Category>,
        }

        impl SqlPost {
            pub fn into_post(self) -> BlogPost {
                // This should pull the markdown content directly from the database
                let HTMLOutput{content,..} = femark::process_markdown_to_html(
                    r#"```Rust
                    move || {
                        async move {
                            match post.await {
                                Ok(Ok(Some(post))) => EitherOf4::A(view! {  <Post post={post}/> }),
                                Ok(Ok(None)) => EitherOf4::B(view! {  <p>"Post Not Found"</p> }),
                                Ok(Err(_)) => EitherOf4::C(view! {  <p>"Server Error"</p> }),
                                Err(_) => EitherOf4::D(view! {  <p>"Server Fn Error"</p> }),
                            }
                        }
                        .suspend()
                        .transition()
                        .with_fallback(view! { <p>"Loading..."</p> })
                        .track()
                    }
                    ```"#
                ).unwrap_or_default();
                BlogPost {
                    id: self.id,
                    title: self.title,
                    description: self.description,
                    hero_image: self.hero_image,
                    published_at: self.published_at.format("%d/%m/%Y").to_string(),
                    content,
                    slug: self.slug,
                    categories: self.categories,
                }
            }
        }
    }
}
  • Fetching data
#[server(GetBlogPost)]
pub async fn get_blog_post(slug: String) -> Result<BlogPost, ServerFnError> {
    use crate::state::AppState;

    let state = expect_context::<AppState>();

    state.db.get_post_by_slug(&slug)
        .await
        .map_err(|e| ServerFnError::ServerError(e.to_string()))

}

#[component]
pub fn BlogPost() -> impl IntoView {
    let params = use_params_map();
    let slug = move || params.with(|params| params.get("slug").unwrap_or_default());
    let post = Resource::new(slug, get_blog_post);

    view! {...
  • Logs:
2024-11-18T22:53:23.426Z DEBUG [femark::parser] Got markdown event ev=Start(CodeBlock(Fenced(Borrowed("Rust"))))
2024-11-18T22:53:23.426Z DEBUG [femark::parser] Got markdown event ev=Text(Borrowed("                    move || {\n                        async move {\n                            match post.await {\n                                Ok(Ok(Some(post))) => EitherOf4::A(view! {  <Post post={post}/> }),\n                                Ok(Ok(None)) => EitherOf4::B(view! {  <p>\"Post Not Found\"</p> }),\n                                Ok(Err(_)) => EitherOf4::C(view! {  <p>\"Server Error\"</p> }),\n                                Err(_) => EitherOf4::D(view! {  <p>\"Server Fn Error\"</p> }),\n                            }\n                        }\n                        .suspend()\n                        .transition()\n                        .with_fallback(view! { <p>\"Loading...\"</p> })\n                        .track()\n                    }\n                    ```"))
2024-11-18T22:53:23.426Z DEBUG [femark::parser] Got markdown event ev=End(CodeBlock(Fenced(Borrowed("Rust"))))
thread 'tokio-runtime-worker' panicked at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\femark-0.1.6\src\tree_sitter_collection.rs:31:10:
called `Result::unwrap()` on an `Err` value: QueryError { row: 42, column: 3, offset: 1172, message: "function_expression", kind: NodeType }
stack backtrace:
   0: std::panicking::begin_panic_handler
             at /rustc/bc5cf994db9fb46712cefd89f78ad7fc51f184a2\library/std\src\panicking.rs:665
   1: core::panicking::panic_fmt
             at /rustc/bc5cf994db9fb46712cefd89f78ad7fc51f184a2\library/core\src\panicking.rs:75
   2: core::result::unwrap_failed
             at /rustc/bc5cf994db9fb46712cefd89f78ad7fc51f184a2\library/core\src\result.rs:1698
   3: enum2$<core::result::Result<tree_sitter_highlight::HighlightConfiguration,tree_sitter::QueryError> >::unwrap
             at C:\Users\KhanhTIMN\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\result.rs:1103
   4: femark::tree_sitter_collection::TreeSitterCollection::typescript
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\femark-0.1.6\src\tree_sitter_collection.rs:25
   5: femark::langs::Langs::new
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\femark-0.1.6\src\langs.rs:116
   6: femark::langs::LANGS::closure$0
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\femark-0.1.6\src\langs.rs:8
   7: core::ops::function::FnOnce::call_once<femark::langs::LANGS::closure_env$0,tuple$<> >
             at C:\Users\KhanhTIMN\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:250
   8: core::ops::function::FnOnce::call_once<femark::langs::Langs (*)(),tuple$<> >
             at C:\Users\KhanhTIMN\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:250
   9: once_cell::sync::impl$11::force::closure$0<femark::langs::Langs,femark::langs::Langs (*)()>
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\once_cell-1.20.2\src\lib.rs:1310
  10: once_cell::sync::impl$6::get_or_init::closure$0<femark::langs::Langs,once_cell::sync::impl$11::force::closure_env$0<femark::langs::Langs,femark::langs::Langs (*)()> >
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\once_cell-1.20.2\src\lib.rs:1120
  11: once_cell::imp::impl$4::initialize::closure$0<femark::langs::Langs,once_cell::sync::impl$6::get_or_init::closure_env$0<femark::langs::Langs,once_cell::sync::impl$11::force::closure_env$0<femark::langs::Langs,femark::langs::Langs (*)()> >,enum2$<once_cell::
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\once_cell-1.20.2\src\imp_std.rs:72
  12: core::ops::function::impls::impl$3::call_mut<tuple$<>,dyn$<core::ops::function::FnMut<tuple$<>,assoc$<Output,bool> > > >
             at C:\Users\KhanhTIMN\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:294
  13: once_cell::imp::initialize_or_wait
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\once_cell-1.20.2\src\imp_std.rs:196
  14: once_cell::imp::OnceCell<femark::langs::Langs>::initialize<femark::langs::Langs,once_cell::sync::impl$6::get_or_init::closure_env$0<femark::langs::Langs,once_cell::sync::impl$11::force::closure_env$0<femark::langs::Langs,femark::langs::Langs (*)()> >,enum2
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\once_cell-1.20.2\src\imp_std.rs:68
  15: once_cell::sync::OnceCell<femark::langs::Langs>::get_or_try_init<femark::langs::Langs,once_cell::sync::impl$6::get_or_init::closure_env$0<femark::langs::Langs,once_cell::sync::impl$11::force::closure_env$0<femark::langs::Langs,femark::langs::Langs (*)()> >
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\once_cell-1.20.2\src\lib.rs:1161
  16: once_cell::sync::OnceCell<femark::langs::Langs>::get_or_init<femark::langs::Langs,once_cell::sync::impl$11::force::closure_env$0<femark::langs::Langs,femark::langs::Langs (*)()> >
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\once_cell-1.20.2\src\lib.rs:1120
  17: once_cell::sync::Lazy<femark::langs::Langs,femark::langs::Langs (*)()>::force<femark::langs::Langs,femark::langs::Langs (*)()>
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\once_cell-1.20.2\src\lib.rs:1309
  18: once_cell::sync::impl$12::deref<femark::langs::Langs,femark::langs::Langs (*)()>
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\once_cell-1.20.2\src\lib.rs:1376
  19: femark::parser::process_stream::closure$0<pulldown_cmark::parse::Parser>
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\femark-0.1.6\src\parser.rs:136
  20: core::ops::function::impls::impl$4::call_once<tuple$<enum2$<pulldown_cmark::Event> >,femark::parser::process_stream::closure_env$0<pulldown_cmark::parse::Parser> >
             at C:\Users\KhanhTIMN\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:305
  21: enum2$<core::option::Option<enum2$<pulldown_cmark::Event> > >::map
             at C:\Users\KhanhTIMN\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\option.rs:1112
  22: core::iter::adapters::map::impl$2::next<enum2$<pulldown_cmark::Event>,pulldown_cmark::parse::Parser,femark::parser::process_stream::closure_env$0<pulldown_cmark::parse::Parser> >
             at C:\Users\KhanhTIMN\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\iter\adapters\map.rs:107
  23: pulldown_cmark::html::HtmlWriter<core::iter::adapters::map::Map<pulldown_cmark::parse::Parser,femark::parser::process_stream::closure_env$0<pulldown_cmark::parse::Parser> >,pulldown_cmark::escape::WriteWrapper<std::io::cursor::Cursor<ref_mut$<alloc::vec::V
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\pulldown-cmark-0.9.6\src\html.rs:87
  24: pulldown_cmark::html::write_html<core::iter::adapters::map::Map<pulldown_cmark::parse::Parser,femark::parser::process_stream::closure_env$0<pulldown_cmark::parse::Parser> >,std::io::cursor::Cursor<ref_mut$<alloc::vec::Vec<u8,alloc::alloc::Global> > > >
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\pulldown-cmark-0.9.6\src\html.rs:477
  25: femark::parser::process_stream<pulldown_cmark::parse::Parser>
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\femark-0.1.6\src\parser.rs:218
  26: femark::process_markdown_to_html_with_frontmatter
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\femark-0.1.6\src\lib.rs:50
  27: femark::process_markdown_to_html
             at C:\Users\KhanhTIMN\.cargo\registry\src\index.crates.io-6f17d22bba15001f\femark-0.1.6\src\lib.rs:24
  28: app::models::post::SqlPost::into_post
             at .\app\src\models\post.rs:38
...

Expected behavior
Code block should render without panicking the server.

Additional context
Any other inputs are processed correctly and return the correct html.
I'm not really sure if this has to do with leptos's server function or my implementation with sqlx though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant