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

1 messages · Page 1 of 1 (latest)

slender wedge
#

Not sure if this is user error or dioxus error but boy it sure is weird. Target is Fullstack + Web. Question above, relevant code in the comments due to character limits.

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 })))?;
subtle viper
#

That sounds like a bug with dioxus. I would expect that code to work

#

Could you open an issue on github about this?

slender wedge
#

Will do! Now that I know it's not something obvious I did I will try and create a simpler reproducer too