We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Raise error when using Scalars (or non strawberry types) with Union
If we do something any of the following:

```python
X = strawberry.Union("X", (int, str))

@strawberry.type
class A:
    field: Union[int, str]


@strawberry.type
class A:
    field: Union[NonStrawberryTypeA, NonStrawberryTypeB]
```

we should get an error informing that:

1. you can't use unions with scalars (not supported by GraphQL)
2. you can only use union with strawberry types

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `strawberry/union.py`
Content:
```
1 from typing import NoReturn, Optional, Tuple, Type
2 
3 
4 class StrawberryUnion:
5     def __init__(
6         self, name: str, types: Tuple[Type, ...], description: Optional[str] = None
7     ):
8         self.name = name
9         self._types = types
10         self.description = description
11 
12     @property
13     def types(self) -> Tuple[Type, ...]:
14         from .types.type_resolver import _resolve_generic_type
15 
16         types = tuple(
17             _resolve_generic_type(t, self.name)
18             for t in self._types
19             if t is not None.__class__
20         )
21 
22         return types
23 
24     def __call__(self, *_args, **_kwargs) -> NoReturn:
25         """Do not use.
26 
27         Used to bypass
28         https://github.com/python/cpython/blob/5efb1a77e75648012f8b52960c8637fc296a5c6d/Lib/typing.py#L148-L149
29         """
30         raise ValueError("Cannot use union type directly")
31 
32 
33 def union(
34     name: str, types: Tuple[Type, ...], *, description: str = None
35 ) -> StrawberryUnion:
36     """Creates a new named Union type.
37 
38     Example usages:
39 
40     >>> strawberry.union("Some Thing", (int, str))
41 
42     >>> @strawberry.type
43     ... class A: ...
44     >>> @strawberry.type
45     ... class B: ...
46     >>> strawberry.union("Name", (A, Optional[B]))
47     """
48 
49     union_definition = StrawberryUnion(name=name, types=types, description=description)
50 
51     return union_definition
52
```

Path: `strawberry/exceptions.py`
Content:
```
1 # TODO: add links to docs
2 
3 from typing import List, Set
4 
5 from graphql import GraphQLObjectType
6 
7 
8 class NotAnEnum(Exception):
9     def __init__(self):
10         message = "strawberry.enum can only be used with subclasses of Enum"
11 
12         super().__init__(message)
13 
14 
15 class MissingReturnAnnotationError(Exception):
16     """The field is missing the return annotation"""
17 
18     def __init__(self, field_name: str):
19         message = (
20             f'Return annotation missing for field "{field_name}", '
21             "did you forget to add it?"
22         )
23 
24         super().__init__(message)
25 
26 
27 class MissingArgumentsAnnotationsError(Exception):
28     """The field is missing the annotation for one or more arguments"""
29 
30     def __init__(self, field_name: str, arguments: Set[str]):
31         arguments_list: List[str] = sorted(list(arguments))
32 
33         if len(arguments_list) == 1:
34             argument = f'argument "{arguments_list[0]}"'
35         else:
36             head = ", ".join(arguments_list[:-1])
37             argument = f'arguments "{head}" and "{arguments_list[-1]}"'
38 
39         message = (
40             f"Missing annotation for {argument} "
41             f'in field "{field_name}", did you forget to add it?'
42         )
43 
44         super().__init__(message)
45 
46 
47 class WrongReturnTypeForUnion(Exception):
48     """The Union type cannot be resolved because it's not a field"""
49 
50     def __init__(self, field_name: str, result_type: str):
51         message = (
52             f'The type "{result_type}" cannot be resolved for the field "{field_name}" '
53             ", are you using a strawberry.field?"
54         )
55 
56         super().__init__(message)
57 
58 
59 class UnallowedReturnTypeForUnion(Exception):
60     """The return type is not in the list of Union types"""
61 
62     def __init__(
63         self, field_name: str, result_type: str, allowed_types: Set[GraphQLObjectType]
64     ):
65         formatted_allowed_types = [type_.name for type_ in allowed_types]
66 
67         message = (
68             f'The type "{result_type}" of the field "{field_name}" '
69             f'is not in the list of the types of the union: "{formatted_allowed_types}"'
70         )
71 
72         super().__init__(message)
73 
74 
75 class MissingTypesForGenericError(Exception):
76     """Raised when a generic types was used without passing any type."""
77 
78     def __init__(self, field_name: str, annotation):
79         message = (
80             f'The type "{annotation.__name__}" of the field "{field_name}" '
81             f"is generic, but no type has been passed"
82         )
83 
84         super().__init__(message)
85 
86 
87 class UnsupportedTypeError(Exception):
88     def __init__(self, annotation):
89         message = f"{annotation} conversion is not supported"
90 
91         super().__init__(message)
92 
93 
94 class MissingFieldAnnotationError(Exception):
95     def __init__(self, field_name: str):
96         message = (
97             f'Unable to determine the type of field "{field_name}". Either '
98             f"annotate it directly, or provide a typed resolver using "
99             f"@strawberry.field."
100         )
101 
102         super().__init__(message)
103 
104 
105 class PrivateStrawberryFieldError(Exception):
106     def __init__(self, field_name: str, type_name: str):
107         message = (
108             f"Field {field_name} on type {type_name} cannot be both "
109             "private and a strawberry.field"
110         )
111 
112         super().__init__(message)
113 
114 
115 class MultipleStrawberryArgumentsError(Exception):
116     def __init__(self, field_name: str, argument_name: str):
117         message = (
118             f"Annotation for argument `{argument_name}` on field "
119             f"`{field_name}` cannot have multiple `strawberry.argument`s"
120         )
121 
122         super().__init__(message)
123 
124 
125 class ScalarAlreadyRegisteredError(Exception):
126     def __init__(self, scalar_name: str):
127         message = f"Scalar `{scalar_name}` has already been registered"
128 
129         super().__init__(message)
130 
131 
132 class WrongNumberOfResultsReturned(Exception):
133     def __init__(self, expected: int, received: int):
134         message = (
135             "Received wrong number of results in dataloader, "
136             f"expected: {expected}, received: {received}"
137         )
138 
139         super().__init__(message)
140
```
--- 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/strawberry/exceptions.py b/strawberry/exceptions.py
--- a/strawberry/exceptions.py
+++ b/strawberry/exceptions.py
@@ -72,6 +72,12 @@
         super().__init__(message)
 
 
+class InvalidUnionType(Exception):
+    """The union is constructed with an invalid type"""
+
+    pass
+
+
 class MissingTypesForGenericError(Exception):
     """Raised when a generic types was used without passing any type."""
 
diff --git a/strawberry/union.py b/strawberry/union.py
--- a/strawberry/union.py
+++ b/strawberry/union.py
@@ -1,4 +1,7 @@
-from typing import NoReturn, Optional, Tuple, Type
+from typing import NoReturn, Optional, Tuple, Type, TypeVar
+
+from .exceptions import InvalidUnionType
+from .scalars import SCALAR_TYPES
 
 
 class StrawberryUnion:
@@ -37,8 +40,6 @@
 
     Example usages:
 
-    >>> strawberry.union("Some Thing", (int, str))
-
     >>> @strawberry.type
     ... class A: ...
     >>> @strawberry.type
@@ -46,6 +47,21 @@
     >>> strawberry.union("Name", (A, Optional[B]))
     """
 
+    # Validate types
+    if len(types) == 0:
+        raise TypeError("No types passed to `union`")
+
+    for _type in types:
+        if _type in SCALAR_TYPES:
+            raise InvalidUnionType(
+                f"Scalar type `{_type.__name__}` cannot be used in a GraphQL Union"
+            )
+
+        if not isinstance(_type, TypeVar) and not hasattr(_type, "_type_definition"):
+            raise InvalidUnionType(
+                f"Union type `{_type.__name__}` is not a Strawberry type"
+            )
+
     union_definition = StrawberryUnion(name=name, types=types, description=description)
 
     return union_definition

{"golden_diff": "diff --git a/strawberry/exceptions.py b/strawberry/exceptions.py\n--- a/strawberry/exceptions.py\n+++ b/strawberry/exceptions.py\n@@ -72,6 +72,12 @@\n         super().__init__(message)\n \n \n+class InvalidUnionType(Exception):\n+    \"\"\"The union is constructed with an invalid type\"\"\"\n+\n+    pass\n+\n+\n class MissingTypesForGenericError(Exception):\n     \"\"\"Raised when a generic types was used without passing any type.\"\"\"\n \ndiff --git a/strawberry/union.py b/strawberry/union.py\n--- a/strawberry/union.py\n+++ b/strawberry/union.py\n@@ -1,4 +1,7 @@\n-from typing import NoReturn, Optional, Tuple, Type\n+from typing import NoReturn, Optional, Tuple, Type, TypeVar\n+\n+from .exceptions import InvalidUnionType\n+from .scalars import SCALAR_TYPES\n \n \n class StrawberryUnion:\n@@ -37,8 +40,6 @@\n \n     Example usages:\n \n-    >>> strawberry.union(\"Some Thing\", (int, str))\n-\n     >>> @strawberry.type\n     ... class A: ...\n     >>> @strawberry.type\n@@ -46,6 +47,21 @@\n     >>> strawberry.union(\"Name\", (A, Optional[B]))\n     \"\"\"\n \n+    # Validate types\n+    if len(types) == 0:\n+        raise TypeError(\"No types passed to `union`\")\n+\n+    for _type in types:\n+        if _type in SCALAR_TYPES:\n+            raise InvalidUnionType(\n+                f\"Scalar type `{_type.__name__}` cannot be used in a GraphQL Union\"\n+            )\n+\n+        if not isinstance(_type, TypeVar) and not hasattr(_type, \"_type_definition\"):\n+            raise InvalidUnionType(\n+                f\"Union type `{_type.__name__}` is not a Strawberry type\"\n+            )\n+\n     union_definition = StrawberryUnion(name=name, types=types, description=description)\n \n     return union_definition\n", "issue": "Raise error when using Scalars (or non strawberry types) with Union\nIf we do something any of the following:\r\n\r\n```python\r\nX = strawberry.Union(\"X\", (int, str))\r\n\r\n@strawberry.type\r\nclass A:\r\n    field: Union[int, str]\r\n\r\n\r\n@strawberry.type\r\nclass A:\r\n    field: Union[NonStrawberryTypeA, NonStrawberryTypeB]\r\n```\r\n\r\nwe should get an error informing that:\r\n\r\n1. you can't use unions with scalars (not supported by GraphQL)\r\n2. you can only use union with strawberry types\n", "before_files": [{"content": "from typing import NoReturn, Optional, Tuple, Type\n\n\nclass StrawberryUnion:\n    def __init__(\n        self, name: str, types: Tuple[Type, ...], description: Optional[str] = None\n    ):\n        self.name = name\n        self._types = types\n        self.description = description\n\n    @property\n    def types(self) -> Tuple[Type, ...]:\n        from .types.type_resolver import _resolve_generic_type\n\n        types = tuple(\n            _resolve_generic_type(t, self.name)\n            for t in self._types\n            if t is not None.__class__\n        )\n\n        return types\n\n    def __call__(self, *_args, **_kwargs) -> NoReturn:\n        \"\"\"Do not use.\n\n        Used to bypass\n        https://github.com/python/cpython/blob/5efb1a77e75648012f8b52960c8637fc296a5c6d/Lib/typing.py#L148-L149\n        \"\"\"\n        raise ValueError(\"Cannot use union type directly\")\n\n\ndef union(\n    name: str, types: Tuple[Type, ...], *, description: str = None\n) -> StrawberryUnion:\n    \"\"\"Creates a new named Union type.\n\n    Example usages:\n\n    >>> strawberry.union(\"Some Thing\", (int, str))\n\n    >>> @strawberry.type\n    ... class A: ...\n    >>> @strawberry.type\n    ... class B: ...\n    >>> strawberry.union(\"Name\", (A, Optional[B]))\n    \"\"\"\n\n    union_definition = StrawberryUnion(name=name, types=types, description=description)\n\n    return union_definition\n", "path": "strawberry/union.py"}, {"content": "# TODO: add links to docs\n\nfrom typing import List, Set\n\nfrom graphql import GraphQLObjectType\n\n\nclass NotAnEnum(Exception):\n    def __init__(self):\n        message = \"strawberry.enum can only be used with subclasses of Enum\"\n\n        super().__init__(message)\n\n\nclass MissingReturnAnnotationError(Exception):\n    \"\"\"The field is missing the return annotation\"\"\"\n\n    def __init__(self, field_name: str):\n        message = (\n            f'Return annotation missing for field \"{field_name}\", '\n            \"did you forget to add it?\"\n        )\n\n        super().__init__(message)\n\n\nclass MissingArgumentsAnnotationsError(Exception):\n    \"\"\"The field is missing the annotation for one or more arguments\"\"\"\n\n    def __init__(self, field_name: str, arguments: Set[str]):\n        arguments_list: List[str] = sorted(list(arguments))\n\n        if len(arguments_list) == 1:\n            argument = f'argument \"{arguments_list[0]}\"'\n        else:\n            head = \", \".join(arguments_list[:-1])\n            argument = f'arguments \"{head}\" and \"{arguments_list[-1]}\"'\n\n        message = (\n            f\"Missing annotation for {argument} \"\n            f'in field \"{field_name}\", did you forget to add it?'\n        )\n\n        super().__init__(message)\n\n\nclass WrongReturnTypeForUnion(Exception):\n    \"\"\"The Union type cannot be resolved because it's not a field\"\"\"\n\n    def __init__(self, field_name: str, result_type: str):\n        message = (\n            f'The type \"{result_type}\" cannot be resolved for the field \"{field_name}\" '\n            \", are you using a strawberry.field?\"\n        )\n\n        super().__init__(message)\n\n\nclass UnallowedReturnTypeForUnion(Exception):\n    \"\"\"The return type is not in the list of Union types\"\"\"\n\n    def __init__(\n        self, field_name: str, result_type: str, allowed_types: Set[GraphQLObjectType]\n    ):\n        formatted_allowed_types = [type_.name for type_ in allowed_types]\n\n        message = (\n            f'The type \"{result_type}\" of the field \"{field_name}\" '\n            f'is not in the list of the types of the union: \"{formatted_allowed_types}\"'\n        )\n\n        super().__init__(message)\n\n\nclass MissingTypesForGenericError(Exception):\n    \"\"\"Raised when a generic types was used without passing any type.\"\"\"\n\n    def __init__(self, field_name: str, annotation):\n        message = (\n            f'The type \"{annotation.__name__}\" of the field \"{field_name}\" '\n            f\"is generic, but no type has been passed\"\n        )\n\n        super().__init__(message)\n\n\nclass UnsupportedTypeError(Exception):\n    def __init__(self, annotation):\n        message = f\"{annotation} conversion is not supported\"\n\n        super().__init__(message)\n\n\nclass MissingFieldAnnotationError(Exception):\n    def __init__(self, field_name: str):\n        message = (\n            f'Unable to determine the type of field \"{field_name}\". Either '\n            f\"annotate it directly, or provide a typed resolver using \"\n            f\"@strawberry.field.\"\n        )\n\n        super().__init__(message)\n\n\nclass PrivateStrawberryFieldError(Exception):\n    def __init__(self, field_name: str, type_name: str):\n        message = (\n            f\"Field {field_name} on type {type_name} cannot be both \"\n            \"private and a strawberry.field\"\n        )\n\n        super().__init__(message)\n\n\nclass MultipleStrawberryArgumentsError(Exception):\n    def __init__(self, field_name: str, argument_name: str):\n        message = (\n            f\"Annotation for argument `{argument_name}` on field \"\n            f\"`{field_name}` cannot have multiple `strawberry.argument`s\"\n        )\n\n        super().__init__(message)\n\n\nclass ScalarAlreadyRegisteredError(Exception):\n    def __init__(self, scalar_name: str):\n        message = f\"Scalar `{scalar_name}` has already been registered\"\n\n        super().__init__(message)\n\n\nclass WrongNumberOfResultsReturned(Exception):\n    def __init__(self, expected: int, received: int):\n        message = (\n            \"Received wrong number of results in dataloader, \"\n            f\"expected: {expected}, received: {received}\"\n        )\n\n        super().__init__(message)\n", "path": "strawberry/exceptions.py"}], "after_files": [{"content": "from typing import NoReturn, Optional, Tuple, Type, TypeVar\n\nfrom .exceptions import InvalidUnionType\nfrom .scalars import SCALAR_TYPES\n\n\nclass StrawberryUnion:\n    def __init__(\n        self, name: str, types: Tuple[Type, ...], description: Optional[str] = None\n    ):\n        self.name = name\n        self._types = types\n        self.description = description\n\n    @property\n    def types(self) -> Tuple[Type, ...]:\n        from .types.type_resolver import _resolve_generic_type\n\n        types = tuple(\n            _resolve_generic_type(t, self.name)\n            for t in self._types\n            if t is not None.__class__\n        )\n\n        return types\n\n    def __call__(self, *_args, **_kwargs) -> NoReturn:\n        \"\"\"Do not use.\n\n        Used to bypass\n        https://github.com/python/cpython/blob/5efb1a77e75648012f8b52960c8637fc296a5c6d/Lib/typing.py#L148-L149\n        \"\"\"\n        raise ValueError(\"Cannot use union type directly\")\n\n\ndef union(\n    name: str, types: Tuple[Type, ...], *, description: str = None\n) -> StrawberryUnion:\n    \"\"\"Creates a new named Union type.\n\n    Example usages:\n\n    >>> @strawberry.type\n    ... class A: ...\n    >>> @strawberry.type\n    ... class B: ...\n    >>> strawberry.union(\"Name\", (A, Optional[B]))\n    \"\"\"\n\n    # Validate types\n    if len(types) == 0:\n        raise TypeError(\"No types passed to `union`\")\n\n    for _type in types:\n        if _type in SCALAR_TYPES:\n            raise InvalidUnionType(\n                f\"Scalar type `{_type.__name__}` cannot be used in a GraphQL Union\"\n            )\n\n        if not isinstance(_type, TypeVar) and not hasattr(_type, \"_type_definition\"):\n            raise InvalidUnionType(\n                f\"Union type `{_type.__name__}` is not a Strawberry type\"\n            )\n\n    union_definition = StrawberryUnion(name=name, types=types, description=description)\n\n    return union_definition\n", "path": "strawberry/union.py"}, {"content": "# TODO: add links to docs\n\nfrom typing import List, Set\n\nfrom graphql import GraphQLObjectType\n\n\nclass NotAnEnum(Exception):\n    def __init__(self):\n        message = \"strawberry.enum can only be used with subclasses of Enum\"\n\n        super().__init__(message)\n\n\nclass MissingReturnAnnotationError(Exception):\n    \"\"\"The field is missing the return annotation\"\"\"\n\n    def __init__(self, field_name: str):\n        message = (\n            f'Return annotation missing for field \"{field_name}\", '\n            \"did you forget to add it?\"\n        )\n\n        super().__init__(message)\n\n\nclass MissingArgumentsAnnotationsError(Exception):\n    \"\"\"The field is missing the annotation for one or more arguments\"\"\"\n\n    def __init__(self, field_name: str, arguments: Set[str]):\n        arguments_list: List[str] = sorted(list(arguments))\n\n        if len(arguments_list) == 1:\n            argument = f'argument \"{arguments_list[0]}\"'\n        else:\n            head = \", \".join(arguments_list[:-1])\n            argument = f'arguments \"{head}\" and \"{arguments_list[-1]}\"'\n\n        message = (\n            f\"Missing annotation for {argument} \"\n            f'in field \"{field_name}\", did you forget to add it?'\n        )\n\n        super().__init__(message)\n\n\nclass WrongReturnTypeForUnion(Exception):\n    \"\"\"The Union type cannot be resolved because it's not a field\"\"\"\n\n    def __init__(self, field_name: str, result_type: str):\n        message = (\n            f'The type \"{result_type}\" cannot be resolved for the field \"{field_name}\" '\n            \", are you using a strawberry.field?\"\n        )\n\n        super().__init__(message)\n\n\nclass UnallowedReturnTypeForUnion(Exception):\n    \"\"\"The return type is not in the list of Union types\"\"\"\n\n    def __init__(\n        self, field_name: str, result_type: str, allowed_types: Set[GraphQLObjectType]\n    ):\n        formatted_allowed_types = [type_.name for type_ in allowed_types]\n\n        message = (\n            f'The type \"{result_type}\" of the field \"{field_name}\" '\n            f'is not in the list of the types of the union: \"{formatted_allowed_types}\"'\n        )\n\n        super().__init__(message)\n\n\nclass InvalidUnionType(Exception):\n    \"\"\"The union is constructed with an invalid type\"\"\"\n\n    pass\n\n\nclass MissingTypesForGenericError(Exception):\n    \"\"\"Raised when a generic types was used without passing any type.\"\"\"\n\n    def __init__(self, field_name: str, annotation):\n        message = (\n            f'The type \"{annotation.__name__}\" of the field \"{field_name}\" '\n            f\"is generic, but no type has been passed\"\n        )\n\n        super().__init__(message)\n\n\nclass UnsupportedTypeError(Exception):\n    def __init__(self, annotation):\n        message = f\"{annotation} conversion is not supported\"\n\n        super().__init__(message)\n\n\nclass MissingFieldAnnotationError(Exception):\n    def __init__(self, field_name: str):\n        message = (\n            f'Unable to determine the type of field \"{field_name}\". Either '\n            f\"annotate it directly, or provide a typed resolver using \"\n            f\"@strawberry.field.\"\n        )\n\n        super().__init__(message)\n\n\nclass PrivateStrawberryFieldError(Exception):\n    def __init__(self, field_name: str, type_name: str):\n        message = (\n            f\"Field {field_name} on type {type_name} cannot be both \"\n            \"private and a strawberry.field\"\n        )\n\n        super().__init__(message)\n\n\nclass MultipleStrawberryArgumentsError(Exception):\n    def __init__(self, field_name: str, argument_name: str):\n        message = (\n            f\"Annotation for argument `{argument_name}` on field \"\n            f\"`{field_name}` cannot have multiple `strawberry.argument`s\"\n        )\n\n        super().__init__(message)\n\n\nclass ScalarAlreadyRegisteredError(Exception):\n    def __init__(self, scalar_name: str):\n        message = f\"Scalar `{scalar_name}` has already been registered\"\n\n        super().__init__(message)\n\n\nclass WrongNumberOfResultsReturned(Exception):\n    def __init__(self, expected: int, received: int):\n        message = (\n            \"Received wrong number of results in dataloader, \"\n            f\"expected: {expected}, received: {received}\"\n        )\n\n        super().__init__(message)\n", "path": "strawberry/exceptions.py"}]}