diff --git a/docs/en/src/context.md b/docs/en/src/context.md index 576c5957..b06ca2fe 100644 --- a/docs/en/src/context.md +++ b/docs/en/src/context.md @@ -11,11 +11,11 @@ struct Query; #[Object] impl Query { - async fn borrow_from_context_data<'ctx'>( + async fn borrow_from_context_data<'ctx>( &self, ctx: &'ctx Context<'_> - ) -> &'ctx String { - ctx.data:: + ) -> FieldResult<&'ctx String> { + ctx.data::() } } ``` diff --git a/docs/en/src/define_complex_object.md b/docs/en/src/define_complex_object.md index 6b5f0c28..7893c128 100644 --- a/docs/en/src/define_complex_object.md +++ b/docs/en/src/define_complex_object.md @@ -28,7 +28,7 @@ impl MyObject { ctx: &Context<'_>, #[arg(desc = "Id of object")] id: i64 ) -> FieldResult { - let conn = ctx.data::().take(); + let conn = ctx.data::()?.take(); Ok(conn.query_something(id)?.name) } } diff --git a/docs/zh-CN/src/context.md b/docs/zh-CN/src/context.md index 432aab12..d4a578e6 100644 --- a/docs/zh-CN/src/context.md +++ b/docs/zh-CN/src/context.md @@ -11,11 +11,11 @@ struct Query; #[Object] impl Query { - async fn borrow_from_context_data<'ctx'>( + async fn borrow_from_context_data<'ctx>( &self, ctx: &'ctx Context<'_> - ) -> &'ctx String { - ctx.data:: + ) -> FieldResult<&'ctx String> { + ctx.data::() } } -``` \ No newline at end of file +``` diff --git a/docs/zh-CN/src/define_complex_object.md b/docs/zh-CN/src/define_complex_object.md index c560efd0..d8af5d75 100644 --- a/docs/zh-CN/src/define_complex_object.md +++ b/docs/zh-CN/src/define_complex_object.md @@ -26,7 +26,7 @@ impl MyObject { ctx: &Context<'_>, #[arg(desc = "Id of object")] id: i64 ) -> FieldResult { - let conn = ctx.data::().take(); + let conn = ctx.data::()?.take(); Ok(conn.query_something(id)?.name) } } diff --git a/src/context.rs b/src/context.rs index c3f1cb46..a6ab2be9 100644 --- a/src/context.rs +++ b/src/context.rs @@ -2,7 +2,8 @@ use crate::extensions::Extensions; use crate::parser::query::{Directive, Field, SelectionSet}; use crate::schema::SchemaEnv; use crate::{ - InputValueType, Lookahead, Pos, Positioned, QueryError, QueryResponse, Result, Type, Value, + FieldResult, InputValueType, Lookahead, Pos, Positioned, QueryError, QueryResponse, Result, + Type, Value, }; use async_graphql_parser::query::Document; use async_graphql_parser::UploadValue; @@ -399,12 +400,20 @@ impl<'a, T> ContextBase<'a, T> { /// /// If both `Schema` and `Query` have the same data type, the data in the `Query` is obtained. /// + /// Returns a FieldError if the specified type data does not exist. + pub fn data(&self) -> FieldResult<&D> { + self.data_opt::() + .ok_or_else(|| format!("Data `{}` does not exist.", std::any::type_name::()).into()) + } + + /// Gets the global data defined in the `Context` or `Schema`. + /// /// # Panics /// /// It will panic if the specified data type does not exist. - pub fn data(&self) -> &D { + pub fn data_unchecked(&self) -> &D { self.data_opt::() - .expect("The specified data type does not exist.") + .unwrap_or_else(|| panic!("Data `{}` does not exist.", std::any::type_name::())) } /// Gets the global data defined in the `Context` or `Schema`, returns `None` if the specified type data does not exist. diff --git a/src/lib.rs b/src/lib.rs index 99978912..886311df 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -549,8 +549,8 @@ pub use async_graphql_derive::InputObject; /// #[Object] /// impl TypeA { /// /// Returns data borrowed from the context -/// async fn value_a<'a>(&self, ctx: &'a Context<'_>) -> &'a str { -/// ctx.data::().as_str() +/// async fn value_a<'a>(&self, ctx: &'a Context<'_>) -> FieldResult<&'a str> { +/// Ok(ctx.data::()?.as_str()) /// } /// /// /// Returns data borrowed self diff --git a/tests/mutation.rs b/tests/mutation.rs index 96216a24..f059146b 100644 --- a/tests/mutation.rs +++ b/tests/mutation.rs @@ -16,13 +16,13 @@ pub async fn test_mutation_execution_order() { impl MutationRoot { async fn append1(&self, ctx: &Context<'_>) -> bool { async_std::task::sleep(Duration::from_secs(1)).await; - ctx.data::().lock().await.push(1); + ctx.data_unchecked::().lock().await.push(1); true } async fn append2(&self, ctx: &Context<'_>) -> bool { async_std::task::sleep(Duration::from_millis(500)).await; - ctx.data::().lock().await.push(2); + ctx.data_unchecked::().lock().await.push(2); true } } diff --git a/tests/subscription.rs b/tests/subscription.rs index 09304b7b..bd1e99c2 100644 --- a/tests/subscription.rs +++ b/tests/subscription.rs @@ -157,7 +157,7 @@ pub async fn test_subscription_with_ctx_data() { #[Object] impl MyObject { async fn value(&self, ctx: &Context<'_>) -> i32 { - *ctx.data::() + *ctx.data_unchecked::() } } @@ -166,7 +166,7 @@ pub async fn test_subscription_with_ctx_data() { #[Subscription] impl SubscriptionRoot { async fn values(&self, ctx: &Context<'_>) -> impl Stream { - let value = *ctx.data::(); + let value = *ctx.data_unchecked::(); futures::stream::once(async move { value }) } @@ -217,7 +217,7 @@ pub async fn test_subscription_with_token() { #[Subscription] impl SubscriptionRoot { async fn values(&self, ctx: &Context<'_>) -> FieldResult> { - if ctx.data::().0 != "123456" { + if ctx.data_unchecked::().0 != "123456" { return Err("forbidden".into()); } Ok(futures::stream::once(async move { 100 })) diff --git a/tests/subscription_websocket.rs b/tests/subscription_websocket.rs index 30819d9b..b72aff4d 100644 --- a/tests/subscription_websocket.rs +++ b/tests/subscription_websocket.rs @@ -78,7 +78,7 @@ pub async fn test_subscription_ws_transport_with_token() { #[Subscription] impl SubscriptionRoot { async fn values(&self, ctx: &Context<'_>) -> FieldResult> { - if ctx.data::().0 != "123456" { + if ctx.data_unchecked::().0 != "123456" { return Err("forbidden".into()); } Ok(futures::stream::iter(0..10))