LukeMathWalker / pavex

An easy-to-use Rust framework for building robust and performant APIs
https://pavex.dev
Apache License 2.0
1.74k stars 59 forks source link

Codegen Panic: pre-processor middleware w/mutable dependency injection #320

Closed snarkipus closed 1 month ago

snarkipus commented 3 months ago

I tried this code: repo

Registered a constructor & fallible pre-processor middleware: link

pub fn tickets_bp() -> Blueprint {
    let mut bp = Blueprint::new();

    bp.request_scoped(f!(crate::tickets::TicketForCreate::extract))
        .error_handler(f!(crate::tickets::invalid_ticket));

    bp.request_scoped(f!(crate::ctx::Ctx::new));

    bp.pre_process(f!(super::web::mw_auth::mw_require_auth))
        .error_handler(f!(super::web::mw_auth::mw_auth_error));

    bp.route(POST, "/tickets", f!(self::tickets::post));
    bp.route(GET, "/tickets", f!(self::tickets::get));
    bp.route(DELETE, "/tickets/:id", f!(self::tickets::delete));
    bp
}

Passed a mutable reference to the middleware (note: this works): link

pub async fn mw_require_auth(request_cookies: RequestCookies<'_>, ctx: &mut Ctx) -> Result<Processing, AuthError> {
    [...]
    ctx.set(user_id);

    tracing::Span::current().record("auth_status", "success");
    Ok(Processing::Continue)
}

Access the context in a subsequent hander (note: this breaks):

Instead, this happened: Application fails to build and panics during codegen.

Error

cargo px check:

   Computing package graph
    Computed package graph in 0.102s
   Compiling `bp`, the code generator for `server_sdk`
warning: /home/snarkipus/Projects/rust-edu/Pavex/chone/workspace_hack/Cargo.toml: no edition set: defaulting to the 2015 edition while the latest is 2021
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.05s
    Compiled `bp`, the code generator for `server_sdk`, in 0.062s
  Generating `server_sdk`
warning: /home/snarkipus/Projects/rust-edu/Pavex/chone/workspace_hack/Cargo.toml: no edition set: defaulting to the 2015 edition while the latest is 2021
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.05s
     Running `target/debug/bp`

Backtrace omitted. Run with RUST_BACKTRACE=1 to display it.
Run with RUST_BACKTRACE=full to include source snippets.

The application panicked (crashed).
  Could not find a binding for input type `app::ctx::Ctx` in the input bindings.
  Input bindings: 
  - s_0: &pavex::request::RequestHead, 
  - s_1: &biscotti::Processor, 
  - s_2: &app::configuration::ModelController, 
  - s_3: pavex::request::path::MatchedPathPattern, 
in pavexc/src/compiler/analyses/processing_pipeline/codegen.rs, line 108
thread: main
The invocation of `pavex [...] generate [...]` exited with a non-zero status code: 101
error: Failed to run `bp`, the code generator for package `server_sdk`

Meta

pavex --version:

pavex_cli 0.1.44 (13ff1e0)

rustc --version --verbose:

rustc 1.81.0-nightly (ba1d7f4a0 2024-06-29)
binary: rustc
commit-hash: ba1d7f4a083e6402679105115ded645512a7aea8
commit-date: 2024-06-29
host: x86_64-unknown-linux-gnu
release: 1.81.0-nightly
LLVM version: 18.1.7
Backtrace

```zsh Backtrace (most recent call first): File "", line 0, in pavexc::compiler::analyses::processing_pipeline::codegen::::codegen File "", line 0, in as alloc::vec::spec_from_iter::SpecFromIter>::from_iter File "", line 0, in as core::iter::traits::collect::FromIterator<(K,V)>>::from_iter File "", line 0, in pavexc::compiler::codegen::codegen_app File "", line 0, in pavexc::compiler::app::App::codegen File "", line 0, in pavexc::main File "", line 0, in std::sys_common::backtrace::__rust_begin_short_backtrace File "", line 0, in std::rt::lang_start::{{closure}} File "", line 0, in std::rt::lang_start_internal File "", line 0, in main File "./csu/../sysdeps/nptl/libc_start_call_main.h", line 58, in __libc_start_call_main File "./csu/../csu/libc-start.c", line 360, in __libc_start_main_impl File "", line 0, in _start ```

Not sure if it helps, but I can see the following in the codegen output:

Pre-processing codegen picks it up the context: link

    async fn pre_processing_0(
        v0: &biscotti::Processor,
        v1: &pavex::request::RequestHead,
    ) -> pavex::middleware::Processing {
        [....]
        let mut v4 = app::ctx::Ctx::new();
        let v5 = app::routes::web::mw_auth::mw_require_auth(v3, &mut v4).await;
        [....]
    }

Handler codegen does not (error): link

    async fn handler(
        v0: &app::configuration::ModelController,
        // assuming missing input parameter `vX: &app::ctx::Ctx`
    ) -> pavex::response::Response {
        let v1 = app::routes::web::tickets::get(v0).await; // <--- missing argument for `vX` of type ctx: Ctx
        <pavex::response::Response as pavex::response::IntoResponse>::into_response(v1)
    }
LukeMathWalker commented 1 month ago

This has been fixed in 0.1.47. Thanks for reporting it!