We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
GraphQL response should not include error key if no error occured
The [GraphQL Spec](https://graphql.github.io/graphql-spec/June2018/#sec-Errors) states that:
> If no errors were encountered during the requested operation, the errors entry should not be present in the result.

Currently, if no errors are encountered, starlette will return `{"data": {...}, "errors": null}`. 
This is only a small thing, but enough to break some clients.

I have a PR for this incoming.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `starlette/graphql.py`
Content:
```
1 import json
2 import typing
3 
4 from starlette import status
5 from starlette.background import BackgroundTasks
6 from starlette.concurrency import run_in_threadpool
7 from starlette.requests import Request
8 from starlette.responses import HTMLResponse, JSONResponse, PlainTextResponse, Response
9 from starlette.types import Receive, Scope, Send
10 
11 try:
12     import graphene
13     from graphql.execution.executors.asyncio import AsyncioExecutor
14     from graphql.error import format_error as format_graphql_error
15     from graphql.error import GraphQLError
16 except ImportError:  # pragma: nocover
17     graphene = None  # type: ignore
18     AsyncioExecutor = None  # type: ignore
19     format_graphql_error = None  # type: ignore
20     GraphQLError = None  # type: ignore
21 
22 
23 class GraphQLApp:
24     def __init__(
25         self,
26         schema: "graphene.Schema",
27         executor: typing.Any = None,
28         executor_class: type = None,
29         graphiql: bool = True,
30     ) -> None:
31         self.schema = schema
32         self.graphiql = graphiql
33         if executor is None:
34             # New style in 0.10.0. Use 'executor_class'.
35             # See issue https://github.com/encode/starlette/issues/242
36             self.executor = executor
37             self.executor_class = executor_class
38             self.is_async = executor_class is not None and issubclass(
39                 executor_class, AsyncioExecutor
40             )
41         else:
42             # Old style. Use 'executor'.
43             # We should remove this in the next median/major version bump.
44             self.executor = executor
45             self.executor_class = None
46             self.is_async = isinstance(executor, AsyncioExecutor)
47 
48     async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
49         if self.executor is None and self.executor_class is not None:
50             self.executor = self.executor_class()
51 
52         request = Request(scope, receive=receive)
53         response = await self.handle_graphql(request)
54         await response(scope, receive, send)
55 
56     async def handle_graphql(self, request: Request) -> Response:
57         if request.method in ("GET", "HEAD"):
58             if "text/html" in request.headers.get("Accept", ""):
59                 if not self.graphiql:
60                     return PlainTextResponse(
61                         "Not Found", status_code=status.HTTP_404_NOT_FOUND
62                     )
63                 return await self.handle_graphiql(request)
64 
65             data = request.query_params  # type: typing.Mapping[str, typing.Any]
66 
67         elif request.method == "POST":
68             content_type = request.headers.get("Content-Type", "")
69 
70             if "application/json" in content_type:
71                 data = await request.json()
72             elif "application/graphql" in content_type:
73                 body = await request.body()
74                 text = body.decode()
75                 data = {"query": text}
76             elif "query" in request.query_params:
77                 data = request.query_params
78             else:
79                 return PlainTextResponse(
80                     "Unsupported Media Type",
81                     status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,
82                 )
83 
84         else:
85             return PlainTextResponse(
86                 "Method Not Allowed", status_code=status.HTTP_405_METHOD_NOT_ALLOWED
87             )
88 
89         try:
90             query = data["query"]
91             variables = data.get("variables")
92             operation_name = data.get("operationName")
93         except KeyError:
94             return PlainTextResponse(
95                 "No GraphQL query found in the request",
96                 status_code=status.HTTP_400_BAD_REQUEST,
97             )
98 
99         background = BackgroundTasks()
100         context = {"request": request, "background": background}
101 
102         result = await self.execute(
103             query, variables=variables, context=context, operation_name=operation_name
104         )
105         error_data = (
106             [format_graphql_error(err) for err in result.errors]
107             if result.errors
108             else None
109         )
110         response_data = {"data": result.data, "errors": error_data}
111         status_code = (
112             status.HTTP_400_BAD_REQUEST if result.errors else status.HTTP_200_OK
113         )
114 
115         return JSONResponse(
116             response_data, status_code=status_code, background=background
117         )
118 
119     async def execute(  # type: ignore
120         self, query, variables=None, context=None, operation_name=None
121     ):
122         if self.is_async:
123             return await self.schema.execute(
124                 query,
125                 variables=variables,
126                 operation_name=operation_name,
127                 executor=self.executor,
128                 return_promise=True,
129                 context=context,
130             )
131         else:
132             return await run_in_threadpool(
133                 self.schema.execute,
134                 query,
135                 variables=variables,
136                 operation_name=operation_name,
137                 context=context,
138             )
139 
140     async def handle_graphiql(self, request: Request) -> Response:
141         text = GRAPHIQL.replace("{{REQUEST_PATH}}", json.dumps(request.url.path))
142         return HTMLResponse(text)
143 
144 
145 GRAPHIQL = """
146 <!--
147  *  Copyright (c) Facebook, Inc.
148  *  All rights reserved.
149  *
150  *  This source code is licensed under the license found in the
151  *  LICENSE file in the root directory of this source tree.
152 -->
153 <!DOCTYPE html>
154 <html>
155   <head>
156     <style>
157       body {
158         height: 100%;
159         margin: 0;
160         width: 100%;
161         overflow: hidden;
162       }
163       #graphiql {
164         height: 100vh;
165       }
166     </style>
167     <!--
168       This GraphiQL example depends on Promise and fetch, which are available in
169       modern browsers, but can be "polyfilled" for older browsers.
170       GraphiQL itself depends on React DOM.
171       If you do not want to rely on a CDN, you can host these files locally or
172       include them directly in your favored resource bunder.
173     -->
174     <link href="//cdn.jsdelivr.net/npm/graphiql@0.12.0/graphiql.css" rel="stylesheet"/>
175     <script src="//cdn.jsdelivr.net/npm/whatwg-fetch@2.0.3/fetch.min.js"></script>
176     <script src="//cdn.jsdelivr.net/npm/react@16.2.0/umd/react.production.min.js"></script>
177     <script src="//cdn.jsdelivr.net/npm/react-dom@16.2.0/umd/react-dom.production.min.js"></script>
178     <script src="//cdn.jsdelivr.net/npm/graphiql@0.12.0/graphiql.min.js"></script>
179   </head>
180   <body>
181     <div id="graphiql">Loading...</div>
182     <script>
183       /**
184        * This GraphiQL example illustrates how to use some of GraphiQL's props
185        * in order to enable reading and updating the URL parameters, making
186        * link sharing of queries a little bit easier.
187        *
188        * This is only one example of this kind of feature, GraphiQL exposes
189        * various React params to enable interesting integrations.
190        */
191       // Parse the search string to get url parameters.
192       var search = window.location.search;
193       var parameters = {};
194       search.substr(1).split('&').forEach(function (entry) {
195         var eq = entry.indexOf('=');
196         if (eq >= 0) {
197           parameters[decodeURIComponent(entry.slice(0, eq))] =
198             decodeURIComponent(entry.slice(eq + 1));
199         }
200       });
201       // if variables was provided, try to format it.
202       if (parameters.variables) {
203         try {
204           parameters.variables =
205             JSON.stringify(JSON.parse(parameters.variables), null, 2);
206         } catch (e) {
207           // Do nothing, we want to display the invalid JSON as a string, rather
208           // than present an error.
209         }
210       }
211       // When the query and variables string is edited, update the URL bar so
212       // that it can be easily shared
213       function onEditQuery(newQuery) {
214         parameters.query = newQuery;
215         updateURL();
216       }
217       function onEditVariables(newVariables) {
218         parameters.variables = newVariables;
219         updateURL();
220       }
221       function onEditOperationName(newOperationName) {
222         parameters.operationName = newOperationName;
223         updateURL();
224       }
225       function updateURL() {
226         var newSearch = '?' + Object.keys(parameters).filter(function (key) {
227           return Boolean(parameters[key]);
228         }).map(function (key) {
229           return encodeURIComponent(key) + '=' +
230             encodeURIComponent(parameters[key]);
231         }).join('&');
232         history.replaceState(null, null, newSearch);
233       }
234       // Defines a GraphQL fetcher using the fetch API. You're not required to
235       // use fetch, and could instead implement graphQLFetcher however you like,
236       // as long as it returns a Promise or Observable.
237       function graphQLFetcher(graphQLParams) {
238         // This example expects a GraphQL server at the path /graphql.
239         // Change this to point wherever you host your GraphQL server.
240         return fetch({{REQUEST_PATH}}, {
241           method: 'post',
242           headers: {
243             'Accept': 'application/json',
244             'Content-Type': 'application/json',
245           },
246           body: JSON.stringify(graphQLParams),
247           credentials: 'include',
248         }).then(function (response) {
249           return response.text();
250         }).then(function (responseBody) {
251           try {
252             return JSON.parse(responseBody);
253           } catch (error) {
254             return responseBody;
255           }
256         });
257       }
258       // Render <GraphiQL /> into the body.
259       // See the README in the top level of this module to learn more about
260       // how you can customize GraphiQL by providing different values or
261       // additional child elements.
262       ReactDOM.render(
263         React.createElement(GraphiQL, {
264           fetcher: graphQLFetcher,
265           query: parameters.query,
266           variables: parameters.variables,
267           operationName: parameters.operationName,
268           onEditQuery: onEditQuery,
269           onEditVariables: onEditVariables,
270           onEditOperationName: onEditOperationName
271         }),
272         document.getElementById('graphiql')
273       );
274     </script>
275   </body>
276 </html>
277 """
278
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/starlette/graphql.py b/starlette/graphql.py
--- a/starlette/graphql.py
+++ b/starlette/graphql.py
@@ -107,7 +107,9 @@
             if result.errors
             else None
         )
-        response_data = {"data": result.data, "errors": error_data}
+        response_data = {"data": result.data}
+        if error_data:
+            response_data["errors"] = error_data
         status_code = (
             status.HTTP_400_BAD_REQUEST if result.errors else status.HTTP_200_OK
         )

{"golden_diff": "diff --git a/starlette/graphql.py b/starlette/graphql.py\n--- a/starlette/graphql.py\n+++ b/starlette/graphql.py\n@@ -107,7 +107,9 @@\n             if result.errors\n             else None\n         )\n-        response_data = {\"data\": result.data, \"errors\": error_data}\n+        response_data = {\"data\": result.data}\n+        if error_data:\n+            response_data[\"errors\"] = error_data\n         status_code = (\n             status.HTTP_400_BAD_REQUEST if result.errors else status.HTTP_200_OK\n         )\n", "issue": "GraphQL response should not include error key if no error occured\nThe [GraphQL Spec](https://graphql.github.io/graphql-spec/June2018/#sec-Errors) states that:\r\n> If no errors were encountered during the requested operation, the errors entry should not be present in the result.\r\n\r\nCurrently, if no errors are encountered, starlette will return `{\"data\": {...}, \"errors\": null}`. \r\nThis is only a small thing, but enough to break some clients.\r\n\r\nI have a PR for this incoming.\n", "before_files": [{"content": "import json\nimport typing\n\nfrom starlette import status\nfrom starlette.background import BackgroundTasks\nfrom starlette.concurrency import run_in_threadpool\nfrom starlette.requests import Request\nfrom starlette.responses import HTMLResponse, JSONResponse, PlainTextResponse, Response\nfrom starlette.types import Receive, Scope, Send\n\ntry:\n    import graphene\n    from graphql.execution.executors.asyncio import AsyncioExecutor\n    from graphql.error import format_error as format_graphql_error\n    from graphql.error import GraphQLError\nexcept ImportError:  # pragma: nocover\n    graphene = None  # type: ignore\n    AsyncioExecutor = None  # type: ignore\n    format_graphql_error = None  # type: ignore\n    GraphQLError = None  # type: ignore\n\n\nclass GraphQLApp:\n    def __init__(\n        self,\n        schema: \"graphene.Schema\",\n        executor: typing.Any = None,\n        executor_class: type = None,\n        graphiql: bool = True,\n    ) -> None:\n        self.schema = schema\n        self.graphiql = graphiql\n        if executor is None:\n            # New style in 0.10.0. Use 'executor_class'.\n            # See issue https://github.com/encode/starlette/issues/242\n            self.executor = executor\n            self.executor_class = executor_class\n            self.is_async = executor_class is not None and issubclass(\n                executor_class, AsyncioExecutor\n            )\n        else:\n            # Old style. Use 'executor'.\n            # We should remove this in the next median/major version bump.\n            self.executor = executor\n            self.executor_class = None\n            self.is_async = isinstance(executor, AsyncioExecutor)\n\n    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n        if self.executor is None and self.executor_class is not None:\n            self.executor = self.executor_class()\n\n        request = Request(scope, receive=receive)\n        response = await self.handle_graphql(request)\n        await response(scope, receive, send)\n\n    async def handle_graphql(self, request: Request) -> Response:\n        if request.method in (\"GET\", \"HEAD\"):\n            if \"text/html\" in request.headers.get(\"Accept\", \"\"):\n                if not self.graphiql:\n                    return PlainTextResponse(\n                        \"Not Found\", status_code=status.HTTP_404_NOT_FOUND\n                    )\n                return await self.handle_graphiql(request)\n\n            data = request.query_params  # type: typing.Mapping[str, typing.Any]\n\n        elif request.method == \"POST\":\n            content_type = request.headers.get(\"Content-Type\", \"\")\n\n            if \"application/json\" in content_type:\n                data = await request.json()\n            elif \"application/graphql\" in content_type:\n                body = await request.body()\n                text = body.decode()\n                data = {\"query\": text}\n            elif \"query\" in request.query_params:\n                data = request.query_params\n            else:\n                return PlainTextResponse(\n                    \"Unsupported Media Type\",\n                    status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,\n                )\n\n        else:\n            return PlainTextResponse(\n                \"Method Not Allowed\", status_code=status.HTTP_405_METHOD_NOT_ALLOWED\n            )\n\n        try:\n            query = data[\"query\"]\n            variables = data.get(\"variables\")\n            operation_name = data.get(\"operationName\")\n        except KeyError:\n            return PlainTextResponse(\n                \"No GraphQL query found in the request\",\n                status_code=status.HTTP_400_BAD_REQUEST,\n            )\n\n        background = BackgroundTasks()\n        context = {\"request\": request, \"background\": background}\n\n        result = await self.execute(\n            query, variables=variables, context=context, operation_name=operation_name\n        )\n        error_data = (\n            [format_graphql_error(err) for err in result.errors]\n            if result.errors\n            else None\n        )\n        response_data = {\"data\": result.data, \"errors\": error_data}\n        status_code = (\n            status.HTTP_400_BAD_REQUEST if result.errors else status.HTTP_200_OK\n        )\n\n        return JSONResponse(\n            response_data, status_code=status_code, background=background\n        )\n\n    async def execute(  # type: ignore\n        self, query, variables=None, context=None, operation_name=None\n    ):\n        if self.is_async:\n            return await self.schema.execute(\n                query,\n                variables=variables,\n                operation_name=operation_name,\n                executor=self.executor,\n                return_promise=True,\n                context=context,\n            )\n        else:\n            return await run_in_threadpool(\n                self.schema.execute,\n                query,\n                variables=variables,\n                operation_name=operation_name,\n                context=context,\n            )\n\n    async def handle_graphiql(self, request: Request) -> Response:\n        text = GRAPHIQL.replace(\"{{REQUEST_PATH}}\", json.dumps(request.url.path))\n        return HTMLResponse(text)\n\n\nGRAPHIQL = \"\"\"\n<!--\n *  Copyright (c) Facebook, Inc.\n *  All rights reserved.\n *\n *  This source code is licensed under the license found in the\n *  LICENSE file in the root directory of this source tree.\n-->\n<!DOCTYPE html>\n<html>\n  <head>\n    <style>\n      body {\n        height: 100%;\n        margin: 0;\n        width: 100%;\n        overflow: hidden;\n      }\n      #graphiql {\n        height: 100vh;\n      }\n    </style>\n    <!--\n      This GraphiQL example depends on Promise and fetch, which are available in\n      modern browsers, but can be \"polyfilled\" for older browsers.\n      GraphiQL itself depends on React DOM.\n      If you do not want to rely on a CDN, you can host these files locally or\n      include them directly in your favored resource bunder.\n    -->\n    <link href=\"//cdn.jsdelivr.net/npm/graphiql@0.12.0/graphiql.css\" rel=\"stylesheet\"/>\n    <script src=\"//cdn.jsdelivr.net/npm/whatwg-fetch@2.0.3/fetch.min.js\"></script>\n    <script src=\"//cdn.jsdelivr.net/npm/react@16.2.0/umd/react.production.min.js\"></script>\n    <script src=\"//cdn.jsdelivr.net/npm/react-dom@16.2.0/umd/react-dom.production.min.js\"></script>\n    <script src=\"//cdn.jsdelivr.net/npm/graphiql@0.12.0/graphiql.min.js\"></script>\n  </head>\n  <body>\n    <div id=\"graphiql\">Loading...</div>\n    <script>\n      /**\n       * This GraphiQL example illustrates how to use some of GraphiQL's props\n       * in order to enable reading and updating the URL parameters, making\n       * link sharing of queries a little bit easier.\n       *\n       * This is only one example of this kind of feature, GraphiQL exposes\n       * various React params to enable interesting integrations.\n       */\n      // Parse the search string to get url parameters.\n      var search = window.location.search;\n      var parameters = {};\n      search.substr(1).split('&').forEach(function (entry) {\n        var eq = entry.indexOf('=');\n        if (eq >= 0) {\n          parameters[decodeURIComponent(entry.slice(0, eq))] =\n            decodeURIComponent(entry.slice(eq + 1));\n        }\n      });\n      // if variables was provided, try to format it.\n      if (parameters.variables) {\n        try {\n          parameters.variables =\n            JSON.stringify(JSON.parse(parameters.variables), null, 2);\n        } catch (e) {\n          // Do nothing, we want to display the invalid JSON as a string, rather\n          // than present an error.\n        }\n      }\n      // When the query and variables string is edited, update the URL bar so\n      // that it can be easily shared\n      function onEditQuery(newQuery) {\n        parameters.query = newQuery;\n        updateURL();\n      }\n      function onEditVariables(newVariables) {\n        parameters.variables = newVariables;\n        updateURL();\n      }\n      function onEditOperationName(newOperationName) {\n        parameters.operationName = newOperationName;\n        updateURL();\n      }\n      function updateURL() {\n        var newSearch = '?' + Object.keys(parameters).filter(function (key) {\n          return Boolean(parameters[key]);\n        }).map(function (key) {\n          return encodeURIComponent(key) + '=' +\n            encodeURIComponent(parameters[key]);\n        }).join('&');\n        history.replaceState(null, null, newSearch);\n      }\n      // Defines a GraphQL fetcher using the fetch API. You're not required to\n      // use fetch, and could instead implement graphQLFetcher however you like,\n      // as long as it returns a Promise or Observable.\n      function graphQLFetcher(graphQLParams) {\n        // This example expects a GraphQL server at the path /graphql.\n        // Change this to point wherever you host your GraphQL server.\n        return fetch({{REQUEST_PATH}}, {\n          method: 'post',\n          headers: {\n            'Accept': 'application/json',\n            'Content-Type': 'application/json',\n          },\n          body: JSON.stringify(graphQLParams),\n          credentials: 'include',\n        }).then(function (response) {\n          return response.text();\n        }).then(function (responseBody) {\n          try {\n            return JSON.parse(responseBody);\n          } catch (error) {\n            return responseBody;\n          }\n        });\n      }\n      // Render <GraphiQL /> into the body.\n      // See the README in the top level of this module to learn more about\n      // how you can customize GraphiQL by providing different values or\n      // additional child elements.\n      ReactDOM.render(\n        React.createElement(GraphiQL, {\n          fetcher: graphQLFetcher,\n          query: parameters.query,\n          variables: parameters.variables,\n          operationName: parameters.operationName,\n          onEditQuery: onEditQuery,\n          onEditVariables: onEditVariables,\n          onEditOperationName: onEditOperationName\n        }),\n        document.getElementById('graphiql')\n      );\n    </script>\n  </body>\n</html>\n\"\"\"\n", "path": "starlette/graphql.py"}], "after_files": [{"content": "import json\nimport typing\n\nfrom starlette import status\nfrom starlette.background import BackgroundTasks\nfrom starlette.concurrency import run_in_threadpool\nfrom starlette.requests import Request\nfrom starlette.responses import HTMLResponse, JSONResponse, PlainTextResponse, Response\nfrom starlette.types import Receive, Scope, Send\n\ntry:\n    import graphene\n    from graphql.execution.executors.asyncio import AsyncioExecutor\n    from graphql.error import format_error as format_graphql_error\n    from graphql.error import GraphQLError\nexcept ImportError:  # pragma: nocover\n    graphene = None  # type: ignore\n    AsyncioExecutor = None  # type: ignore\n    format_graphql_error = None  # type: ignore\n    GraphQLError = None  # type: ignore\n\n\nclass GraphQLApp:\n    def __init__(\n        self,\n        schema: \"graphene.Schema\",\n        executor: typing.Any = None,\n        executor_class: type = None,\n        graphiql: bool = True,\n    ) -> None:\n        self.schema = schema\n        self.graphiql = graphiql\n        if executor is None:\n            # New style in 0.10.0. Use 'executor_class'.\n            # See issue https://github.com/encode/starlette/issues/242\n            self.executor = executor\n            self.executor_class = executor_class\n            self.is_async = executor_class is not None and issubclass(\n                executor_class, AsyncioExecutor\n            )\n        else:\n            # Old style. Use 'executor'.\n            # We should remove this in the next median/major version bump.\n            self.executor = executor\n            self.executor_class = None\n            self.is_async = isinstance(executor, AsyncioExecutor)\n\n    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n        if self.executor is None and self.executor_class is not None:\n            self.executor = self.executor_class()\n\n        request = Request(scope, receive=receive)\n        response = await self.handle_graphql(request)\n        await response(scope, receive, send)\n\n    async def handle_graphql(self, request: Request) -> Response:\n        if request.method in (\"GET\", \"HEAD\"):\n            if \"text/html\" in request.headers.get(\"Accept\", \"\"):\n                if not self.graphiql:\n                    return PlainTextResponse(\n                        \"Not Found\", status_code=status.HTTP_404_NOT_FOUND\n                    )\n                return await self.handle_graphiql(request)\n\n            data = request.query_params  # type: typing.Mapping[str, typing.Any]\n\n        elif request.method == \"POST\":\n            content_type = request.headers.get(\"Content-Type\", \"\")\n\n            if \"application/json\" in content_type:\n                data = await request.json()\n            elif \"application/graphql\" in content_type:\n                body = await request.body()\n                text = body.decode()\n                data = {\"query\": text}\n            elif \"query\" in request.query_params:\n                data = request.query_params\n            else:\n                return PlainTextResponse(\n                    \"Unsupported Media Type\",\n                    status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,\n                )\n\n        else:\n            return PlainTextResponse(\n                \"Method Not Allowed\", status_code=status.HTTP_405_METHOD_NOT_ALLOWED\n            )\n\n        try:\n            query = data[\"query\"]\n            variables = data.get(\"variables\")\n            operation_name = data.get(\"operationName\")\n        except KeyError:\n            return PlainTextResponse(\n                \"No GraphQL query found in the request\",\n                status_code=status.HTTP_400_BAD_REQUEST,\n            )\n\n        background = BackgroundTasks()\n        context = {\"request\": request, \"background\": background}\n\n        result = await self.execute(\n            query, variables=variables, context=context, operation_name=operation_name\n        )\n        error_data = (\n            [format_graphql_error(err) for err in result.errors]\n            if result.errors\n            else None\n        )\n        response_data = {\"data\": result.data}\n        if error_data:\n            response_data[\"errors\"] = error_data\n        status_code = (\n            status.HTTP_400_BAD_REQUEST if result.errors else status.HTTP_200_OK\n        )\n\n        return JSONResponse(\n            response_data, status_code=status_code, background=background\n        )\n\n    async def execute(  # type: ignore\n        self, query, variables=None, context=None, operation_name=None\n    ):\n        if self.is_async:\n            return await self.schema.execute(\n                query,\n                variables=variables,\n                operation_name=operation_name,\n                executor=self.executor,\n                return_promise=True,\n                context=context,\n            )\n        else:\n            return await run_in_threadpool(\n                self.schema.execute,\n                query,\n                variables=variables,\n                operation_name=operation_name,\n                context=context,\n            )\n\n    async def handle_graphiql(self, request: Request) -> Response:\n        text = GRAPHIQL.replace(\"{{REQUEST_PATH}}\", json.dumps(request.url.path))\n        return HTMLResponse(text)\n\n\nGRAPHIQL = \"\"\"\n<!--\n *  Copyright (c) Facebook, Inc.\n *  All rights reserved.\n *\n *  This source code is licensed under the license found in the\n *  LICENSE file in the root directory of this source tree.\n-->\n<!DOCTYPE html>\n<html>\n  <head>\n    <style>\n      body {\n        height: 100%;\n        margin: 0;\n        width: 100%;\n        overflow: hidden;\n      }\n      #graphiql {\n        height: 100vh;\n      }\n    </style>\n    <!--\n      This GraphiQL example depends on Promise and fetch, which are available in\n      modern browsers, but can be \"polyfilled\" for older browsers.\n      GraphiQL itself depends on React DOM.\n      If you do not want to rely on a CDN, you can host these files locally or\n      include them directly in your favored resource bunder.\n    -->\n    <link href=\"//cdn.jsdelivr.net/npm/graphiql@0.12.0/graphiql.css\" rel=\"stylesheet\"/>\n    <script src=\"//cdn.jsdelivr.net/npm/whatwg-fetch@2.0.3/fetch.min.js\"></script>\n    <script src=\"//cdn.jsdelivr.net/npm/react@16.2.0/umd/react.production.min.js\"></script>\n    <script src=\"//cdn.jsdelivr.net/npm/react-dom@16.2.0/umd/react-dom.production.min.js\"></script>\n    <script src=\"//cdn.jsdelivr.net/npm/graphiql@0.12.0/graphiql.min.js\"></script>\n  </head>\n  <body>\n    <div id=\"graphiql\">Loading...</div>\n    <script>\n      /**\n       * This GraphiQL example illustrates how to use some of GraphiQL's props\n       * in order to enable reading and updating the URL parameters, making\n       * link sharing of queries a little bit easier.\n       *\n       * This is only one example of this kind of feature, GraphiQL exposes\n       * various React params to enable interesting integrations.\n       */\n      // Parse the search string to get url parameters.\n      var search = window.location.search;\n      var parameters = {};\n      search.substr(1).split('&').forEach(function (entry) {\n        var eq = entry.indexOf('=');\n        if (eq >= 0) {\n          parameters[decodeURIComponent(entry.slice(0, eq))] =\n            decodeURIComponent(entry.slice(eq + 1));\n        }\n      });\n      // if variables was provided, try to format it.\n      if (parameters.variables) {\n        try {\n          parameters.variables =\n            JSON.stringify(JSON.parse(parameters.variables), null, 2);\n        } catch (e) {\n          // Do nothing, we want to display the invalid JSON as a string, rather\n          // than present an error.\n        }\n      }\n      // When the query and variables string is edited, update the URL bar so\n      // that it can be easily shared\n      function onEditQuery(newQuery) {\n        parameters.query = newQuery;\n        updateURL();\n      }\n      function onEditVariables(newVariables) {\n        parameters.variables = newVariables;\n        updateURL();\n      }\n      function onEditOperationName(newOperationName) {\n        parameters.operationName = newOperationName;\n        updateURL();\n      }\n      function updateURL() {\n        var newSearch = '?' + Object.keys(parameters).filter(function (key) {\n          return Boolean(parameters[key]);\n        }).map(function (key) {\n          return encodeURIComponent(key) + '=' +\n            encodeURIComponent(parameters[key]);\n        }).join('&');\n        history.replaceState(null, null, newSearch);\n      }\n      // Defines a GraphQL fetcher using the fetch API. You're not required to\n      // use fetch, and could instead implement graphQLFetcher however you like,\n      // as long as it returns a Promise or Observable.\n      function graphQLFetcher(graphQLParams) {\n        // This example expects a GraphQL server at the path /graphql.\n        // Change this to point wherever you host your GraphQL server.\n        return fetch({{REQUEST_PATH}}, {\n          method: 'post',\n          headers: {\n            'Accept': 'application/json',\n            'Content-Type': 'application/json',\n          },\n          body: JSON.stringify(graphQLParams),\n          credentials: 'include',\n        }).then(function (response) {\n          return response.text();\n        }).then(function (responseBody) {\n          try {\n            return JSON.parse(responseBody);\n          } catch (error) {\n            return responseBody;\n          }\n        });\n      }\n      // Render <GraphiQL /> into the body.\n      // See the README in the top level of this module to learn more about\n      // how you can customize GraphiQL by providing different values or\n      // additional child elements.\n      ReactDOM.render(\n        React.createElement(GraphiQL, {\n          fetcher: graphQLFetcher,\n          query: parameters.query,\n          variables: parameters.variables,\n          operationName: parameters.operationName,\n          onEditQuery: onEditQuery,\n          onEditVariables: onEditVariables,\n          onEditOperationName: onEditOperationName\n        }),\n        document.getElementById('graphiql')\n      );\n    </script>\n  </body>\n</html>\n\"\"\"\n", "path": "starlette/graphql.py"}]}