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

Bug with context and server functions...context in _second_ called function not found. #3500

Open
Houndie opened this issue Jan 4, 2025 · 0 comments

Comments

@Houndie
Copy link

Houndie commented Jan 4, 2025

Problem

This is a repost from the dioxus discord, suspected there to be a bug: https://discord.com/channels/899851952891002890/1325129360193224714

Not sure if this is user error or dioxus error but boy it sure is weird. Target is Fullstack + Web. Question above, relevant code below

I have two server functions, both very similar. They each reference a backend baked into the context. Note that while the backend is called AnyService in both functions, these are unique types in different modules. Both of these backends are inserted into the context using dioxus's axum launch compatibility (not the launch API).

I have a component that calls both of these functions during the initial SSR. Here's the weird part: If I call organization::query first, followed by event::query I get the following error message: odr_server::server_functions::event::server_only::AnyService not found in server context. Weird but okay. However, if I transpose the calls so that I call event::query before organization::query, I get odr_server::server_functions::organization::server_only::AnyService not found in server context. So which ever server function I call first succeeds, and then the follow up fails. If I remove one of the calls, the other one succeeds just fine.

Here's the relevant bits of code:

Server functions:

// organization.rs
#[server]
pub async fn query(
    request: ProtoWrapper<QueryOrganizationsRequest>,
) -> Result<ProtoWrapper<QueryOrganizationsResponse>, ServerFnError> {
    use crate::server_functions::status_to_server_fn_error;

    let service: AnyService = extract::<FromContext<AnyService>, _>().await?.0;
    service
        .query(tonic::Request::new(request.0))
        .await
        .map(|r| ProtoWrapper(r.into_inner()))
        .map_err(status_to_server_fn_error)
}
// event.rs
[server]
pub async fn query(
    request: ProtoWrapper<QueryEventsRequest>,
) -> Result<ProtoWrapper<QueryEventsResponse>, ServerFnError> {
    use crate::server_functions::status_to_server_fn_error;

    let service: AnyService = extract::<FromContext<AnyService>, _>().await?.0;
    service
        .query(tonic::Request::new(request.0))
        .await
        .map(|r| ProtoWrapper(r.into_inner()))
        .map_err(status_to_server_fn_error)
}

Context seeding and server launch:

let organization_provider_state = Box::new(move || {
    Box::new(AnyOrganizationService::new_sqlite(
        organization_service.clone(),
    )) as Box<dyn std::any::Any>
})
    as Box<dyn Fn() -> Box<dyn std::any::Any> + Send + Sync + 'static>;

 let event_provider_state = Box::new(move || {
    Box::new(AnyEventService::new_sqlite(event_service.clone())) as Box<dyn std::any::Any>
})
    as Box<dyn Fn() -> Box<dyn std::any::Any> + Send + Sync + 'static>;

let dioxus_config = ServeConfig::builder()
    .context_providers(Arc::new(vec![
        event_provider_state,
        organization_provider_state,
    ]))
    .build()?;

let webserver =
    axum::Router::new().serve_dioxus_application(dioxus_config, crate::view::app::App);

And the call site:

let organizations_response = use_server_future(move || {
    query_organizations(ProtoWrapper(QueryOrganizationsRequest {
        query: Some(OrganizationQuery {
            query: Some(organization_query::Query::Id(StringQuery {
                operator: Some(string_query::Operator::Equals(org_id())),
            })),
        }),
    }))
})?;

let events_response =
    use_server_future(move || query_events(ProtoWrapper(QueryEventsRequest { query: None })))?;

Steps To Reproduce

Steps to reproduce the behavior:

Create something similar to the scenario above

Expected behavior

Both server functions should run without incident.

Screenshots

Environment:

  • Dioxus version: 1.60.0
  • Rust version: 1.83.0
  • OS info: NixOS
  • App platform: Fullstack + Web

Questionnaire

If I have time I will try to create a minimal reproducer and maybe debug this a bit but I wanted to get this out as is in case I don't

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