From f04434416bc6e36924f725aa578440b1b881eb84 Mon Sep 17 00:00:00 2001
From: xDarksome <dev@darkso.me>
Date: Tue, 11 May 2021 10:43:52 +0300
Subject: [PATCH] Fix subscription error extensions (#927)

---
 .../juniper_tests/src/issue_925.rs            | 69 +++++++++++++++++++
 integration_tests/juniper_tests/src/lib.rs    |  2 +
 juniper_codegen/src/util/mod.rs               |  2 +-
 3 files changed, 72 insertions(+), 1 deletion(-)
 create mode 100644 integration_tests/juniper_tests/src/issue_925.rs

diff --git a/integration_tests/juniper_tests/src/issue_925.rs b/integration_tests/juniper_tests/src/issue_925.rs
new file mode 100644
index 00000000..45180262
--- /dev/null
+++ b/integration_tests/juniper_tests/src/issue_925.rs
@@ -0,0 +1,69 @@
+use juniper::*;
+
+use futures::stream::BoxStream;
+
+#[derive(juniper::GraphQLObject)]
+struct User {
+    name: String,
+}
+
+struct Error;
+
+impl<S: ScalarValue> IntoFieldError<S> for Error {
+    fn into_field_error(self) -> FieldError<S> {
+        let a = Value::Scalar(S::from(42));
+        let mut extensions = Object::with_capacity(1);
+        let _ = extensions.add_field("a", a);
+        FieldError::new("oops", Value::Object(extensions))
+    }
+}
+
+struct SubscriptionsRoot;
+
+#[graphql_subscription(name = "Subscription")]
+impl SubscriptionsRoot {
+    async fn users() -> Result<BoxStream<'static, User>, Error> {
+        Ok(users_stream()?)
+    }
+}
+
+fn users_stream() -> Result<BoxStream<'static, User>, Error> {
+    Err(Error)
+}
+
+struct Query;
+
+#[juniper::graphql_object]
+impl Query {
+    fn users() -> Vec<User> {
+        vec![]
+    }
+}
+
+type Schema = juniper::RootNode<'static, Query, EmptyMutation<()>, SubscriptionsRoot>;
+
+#[tokio::test]
+async fn test_error_extensions() {
+    let sub = r#"
+        subscription Users {
+            users {
+                name
+            }
+        }
+    "#;
+
+    let (_, errors) = juniper::resolve_into_stream(
+        sub,
+        None,
+        &Schema::new(Query, EmptyMutation::new(), SubscriptionsRoot),
+        &Variables::new(),
+        &(),
+    )
+    .await
+    .unwrap();
+
+    assert_eq!(
+        errors.first().unwrap().error().extensions(),
+        &graphql_value!({ "a": 42 })
+    );
+}
diff --git a/integration_tests/juniper_tests/src/lib.rs b/integration_tests/juniper_tests/src/lib.rs
index a4a9c97f..0da4dad4 100644
--- a/integration_tests/juniper_tests/src/lib.rs
+++ b/integration_tests/juniper_tests/src/lib.rs
@@ -23,4 +23,6 @@ mod issue_914;
 #[cfg(test)]
 mod issue_922;
 #[cfg(test)]
+mod issue_925;
+#[cfg(test)]
 mod pre_parse;
diff --git a/juniper_codegen/src/util/mod.rs b/juniper_codegen/src/util/mod.rs
index d007e173..64c9caa4 100644
--- a/juniper_codegen/src/util/mod.rs
+++ b/juniper_codegen/src/util/mod.rs
@@ -1271,7 +1271,7 @@ impl GraphQLTypeDefiniton {
                 quote!(
                     #name => {
                         ::juniper::futures::FutureExt::boxed(async move {
-                            let res #_type = { #code };
+                            let res #_type = async { #code }.await;
                             let res = ::juniper::IntoFieldResult::<_, #scalar>::into_result(res)?;
                             let executor= executor.as_owned_executor();
                             let f = res.then(move |res| {