From a4db80bdc9f584f3d3932dbafb856cf72d88d8b9 Mon Sep 17 00:00:00 2001 From: Sunli Date: Sun, 4 Apr 2021 14:43:23 +0800 Subject: [PATCH] Update subscription.rs --- derive/src/subscription.rs | 26 +++++++++++++++++++------- integrations/warp/src/subscription.rs | 5 ++++- src/extensions/tracing.rs | 3 +-- src/resolver_utils/container.rs | 15 --------------- src/resolver_utils/list.rs | 5 +++-- 5 files changed, 27 insertions(+), 27 deletions(-) diff --git a/derive/src/subscription.rs b/derive/src/subscription.rs index 2896d6d7..f6f40fff 100644 --- a/derive/src/subscription.rs +++ b/derive/src/subscription.rs @@ -316,7 +316,9 @@ pub fn generate( self.#ident(ctx, #(#use_params),*) .await .map_err(|err| { - err.into_server_error().at(ctx.item.pos) + err.into_server_error() + .at(ctx.item.pos) + .path(#crate_name::PathSegment::Field(::std::borrow::ToOwned::to_owned(&*field_name))) })? }; @@ -325,14 +327,18 @@ pub fn generate( None => None, }; let guard = guard.map(|guard| quote! { - #guard.check(ctx).await.map_err(|err| err.into_server_error().at(ctx.item.pos))?; + #guard.check(ctx).await.map_err(|err| { + err.into_server_error() + .at(ctx.item.pos) + .path(#crate_name::PathSegment::Field(::std::borrow::ToOwned::to_owned(&*field_name))) + })?; }); let stream_fn = quote! { - #(#get_params)* - #guard let field_name = ::std::clone::Clone::clone(&ctx.item.node.response_key().node); let field = ::std::sync::Arc::new(::std::clone::Clone::clone(&ctx.item)); + #(#get_params)* + #guard let pos = ctx.item.pos; let schema_env = ::std::clone::Clone::clone(&ctx.schema_env); @@ -373,7 +379,11 @@ pub fn generate( map.insert(::std::clone::Clone::clone(&field_name), value.unwrap_or_default()); #crate_name::Response::new(#crate_name::Value::Object(map)) }) - .unwrap_or_else(|err| #crate_name::Response::from_errors(::std::vec![err])) + .unwrap_or_else(|err| { + #crate_name::Response::from_errors(::std::vec![ + err.path(#crate_name::PathSegment::Field(::std::borrow::ToOwned::to_owned(&*field_name))) + ]) + }) }; #crate_name::futures_util::pin_mut!(execute_fut); ::std::result::Result::Ok(query_env.extensions.execute(&mut execute_fut).await) @@ -387,8 +397,10 @@ pub fn generate( if *errored { return #crate_name::futures_util::future::ready(::std::option::Option::None); } - if item.is_err() { - *errored = true; + match &item { + ::std::result::Result::Err(_) => *errored = true, + ::std::result::Result::Ok(resp) if resp.is_err() => *errored = true, + _ => {} } #crate_name::futures_util::future::ready(::std::option::Option::Some(item)) }, diff --git a/integrations/warp/src/subscription.rs b/integrations/warp/src/subscription.rs index 3b6c5e1e..92f1f3a0 100644 --- a/integrations/warp/src/subscription.rs +++ b/integrations/warp/src/subscription.rs @@ -72,7 +72,10 @@ where Mutation: ObjectType + 'static, Subscription: SubscriptionType + 'static, F: FnOnce(serde_json::Value) -> R + Clone + Send + 'static, - R: Future> + Send + 'static, { graphql_subscription_with_data_and_callbacks(schema, initializer, ||{}, ||{}) } + R: Future> + Send + 'static, +{ + graphql_subscription_with_data_and_callbacks(schema, initializer, || {}, || {}) +} /// GraphQL subscription filter /// diff --git a/src/extensions/tracing.rs b/src/extensions/tracing.rs index 25614704..8eb35b38 100644 --- a/src/extensions/tracing.rs +++ b/src/extensions/tracing.rs @@ -1,13 +1,13 @@ use std::sync::Arc; use futures_util::stream::BoxStream; +use futures_util::TryFutureExt; use tracing_futures::Instrument; use tracinglib::{span, Level}; use crate::extensions::{ Extension, ExtensionContext, ExtensionFactory, NextExtension, ResolveInfo, }; -use crate::futures_util::TryFutureExt; use crate::parser::types::ExecutableDocument; use crate::{Response, ServerError, ServerResult, ValidationResult, Value, Variables}; @@ -22,7 +22,6 @@ use crate::{Response, ServerError, ServerResult, ValidationResult, Value, Variab /// ```no_run /// use async_graphql::*; /// use async_graphql::extensions::Tracing; -/// use tracing::{span, Level, Instrument}; /// /// #[derive(SimpleObject)] /// struct Query { diff --git a/src/resolver_utils/container.rs b/src/resolver_utils/container.rs index f7c4ed1a..46cca142 100644 --- a/src/resolver_utils/container.rs +++ b/src/resolver_utils/container.rs @@ -169,7 +169,6 @@ impl<'a> Fields<'a> { } self.0.push(Box::pin({ - // TODO: investigate removing this let ctx = ctx.clone(); async move { let ctx_field = ctx.with_field(field); @@ -264,20 +263,6 @@ impl<'a> Fields<'a> { .map_or(false, |interfaces| interfaces.contains(condition)) }); if applies_concrete_object { - // The fragment applies to the concrete object type. - - // TODO: This solution isn't ideal. If there are two interfaces InterfaceA - // and InterfaceB and one type MyObj that implements both, then if you have - // a type condition for `InterfaceA` on an `InterfaceB` and when resolving, - // the `InterfaceB` is actually a `MyObj` then the contents of the fragment - // will be treated as a `MyObj` rather than an `InterfaceB`. Example: - // - // myObjAsInterfaceB { - // ... on InterfaceA { - // # here you can query MyObj fields even when you should only be - // # able to query InterfaceA fields. - // } - // } root.collect_all_fields(&ctx.with_selection_set(selection_set), self)?; } else if type_condition.map_or(true, |condition| T::type_name() == condition) { // The fragment applies to an interface type. diff --git a/src/resolver_utils/list.rs b/src/resolver_utils/list.rs index 92f6d8f4..cf2cccba 100644 --- a/src/resolver_utils/list.rs +++ b/src/resolver_utils/list.rs @@ -10,14 +10,15 @@ pub async fn resolve_list<'a, T: OutputType + 'a>( len: Option, ) -> ServerResult { let extensions = &ctx.query_env.extensions; - - if extensions.is_empty() { + if !extensions.is_empty() { let mut futures = len.map(Vec::with_capacity).unwrap_or_default(); for (idx, item) in iter.into_iter().enumerate() { futures.push({ let ctx = ctx.clone(); async move { let ctx_idx = ctx.with_index(idx); + let extensions = &ctx.query_env.extensions; + let resolve_info = ResolveInfo { path_node: ctx_idx.path_node.as_ref().unwrap(), parent_type: &Vec::::type_name(),