We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Raising Exceptions in sub-applications routes
### Checklist

- [X] The bug is reproducible against the latest release or `master`.
- [X] There are no similar issues or pull requests to fix it yet.

### Describe the bug

Let's start with this PR: #1262

It's about preventing raise `anyio.ExceptionGroup` in views under a `BaseHTTPMiddleware`. PR resolve that problem with nonlocal variable that stores our exception. But in the case of sub-applications, it does not work. 

As I can see (fyi I am not good at asyncio), in the case below, we reach and read a response before we raise an exception and store it to our nonlocal variable:

fragment of `BaseHTTPMiddleware.__call__`
```python
async def call_next(request: Request) -> Response:
    app_exc: typing.Optional[Exception] = None
    send_stream, recv_stream = anyio.create_memory_object_stream()

    async def coro() -> None:
        nonlocal app_exc

        async with send_stream:
            try:
                task = await self.app(scope, request.receive, send_stream.send)
            except Exception as exc:
                app_exc = exc

    task_group.start_soon(coro)

    try:
        message = await recv_stream.receive()
    except anyio.EndOfStream:
        if app_exc is not None:
            raise app_exc
        raise RuntimeError("No response returned.")
    
    ...
    response = StreamingResponse(
        status_code=message["status"], content=body_stream()
    )
    response.raw_headers = message["headers"]
    return response
```

in this moment: `except anyio.EndOfStream:` exception still no raised.

### Steps to reproduce the bug

```python
import httpx
import pytest
from fastapi import FastAPI, APIRouter
from starlette.middleware import Middleware
from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
from starlette.requests import Request
from starlette.responses import Response
from starlette.routing import Route


class SomeError(Exception):
    pass


class SomeMiddleware(BaseHTTPMiddleware):
    async def dispatch(
        self, request: Request, call_next: RequestResponseEndpoint
    ) -> Response:
        return await call_next(request)

# Drop (or use not BaseHTTPMiddleware based) middleware and test works fine
app = FastAPI(middleware=[Middleware(SomeMiddleware), ])


async def simple_route(request: Request):
    raise SomeError


another_router = APIRouter(
    routes=[Route('/simple-route/', simple_route, methods=['GET'])]
)
sub_app = FastAPI()
sub_app.include_router(another_router)
app.router.mount(f'/api', sub_app)


@pytest.mark.asyncio
async def test_simple_route():
    async with httpx.AsyncClient(app=app) as client:
        with pytest.raises(SomeError):
            await client.get("http://testserver/api/simple-route/")

```

### Expected behavior

An exception was raised and caught by pytest exception

### Actual behavior

An exception wasn't raised

### Debugging material

_No response_

### Environment

macOS Monterey 12.0.1, starlette 0.17.1, Python 3.9.9


### Additional context

_No response_

--- 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/middleware/base.py`
Content:
```
1 import typing
2 
3 import anyio
4 
5 from starlette.requests import Request
6 from starlette.responses import Response, StreamingResponse
7 from starlette.types import ASGIApp, Receive, Scope, Send
8 
9 RequestResponseEndpoint = typing.Callable[[Request], typing.Awaitable[Response]]
10 DispatchFunction = typing.Callable[
11     [Request, RequestResponseEndpoint], typing.Awaitable[Response]
12 ]
13 
14 
15 class BaseHTTPMiddleware:
16     def __init__(self, app: ASGIApp, dispatch: DispatchFunction = None) -> None:
17         self.app = app
18         self.dispatch_func = self.dispatch if dispatch is None else dispatch
19 
20     async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
21         if scope["type"] != "http":
22             await self.app(scope, receive, send)
23             return
24 
25         async def call_next(request: Request) -> Response:
26             app_exc: typing.Optional[Exception] = None
27             send_stream, recv_stream = anyio.create_memory_object_stream()
28 
29             async def coro() -> None:
30                 nonlocal app_exc
31 
32                 async with send_stream:
33                     try:
34                         await self.app(scope, request.receive, send_stream.send)
35                     except Exception as exc:
36                         app_exc = exc
37 
38             task_group.start_soon(coro)
39 
40             try:
41                 message = await recv_stream.receive()
42             except anyio.EndOfStream:
43                 if app_exc is not None:
44                     raise app_exc
45                 raise RuntimeError("No response returned.")
46 
47             assert message["type"] == "http.response.start"
48 
49             async def body_stream() -> typing.AsyncGenerator[bytes, None]:
50                 async with recv_stream:
51                     async for message in recv_stream:
52                         assert message["type"] == "http.response.body"
53                         yield message.get("body", b"")
54 
55             response = StreamingResponse(
56                 status_code=message["status"], content=body_stream()
57             )
58             response.raw_headers = message["headers"]
59             return response
60 
61         async with anyio.create_task_group() as task_group:
62             request = Request(scope, receive=receive)
63             response = await self.dispatch_func(request, call_next)
64             await response(scope, receive, send)
65             task_group.cancel_scope.cancel()
66 
67     async def dispatch(
68         self, request: Request, call_next: RequestResponseEndpoint
69     ) -> Response:
70         raise NotImplementedError()  # pragma: no cover
71
```
--- 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/middleware/base.py b/starlette/middleware/base.py
--- a/starlette/middleware/base.py
+++ b/starlette/middleware/base.py
@@ -52,6 +52,9 @@
                         assert message["type"] == "http.response.body"
                         yield message.get("body", b"")
 
+                if app_exc is not None:
+                    raise app_exc
+
             response = StreamingResponse(
                 status_code=message["status"], content=body_stream()
             )

{"golden_diff": "diff --git a/starlette/middleware/base.py b/starlette/middleware/base.py\n--- a/starlette/middleware/base.py\n+++ b/starlette/middleware/base.py\n@@ -52,6 +52,9 @@\n                         assert message[\"type\"] == \"http.response.body\"\n                         yield message.get(\"body\", b\"\")\n \n+                if app_exc is not None:\n+                    raise app_exc\n+\n             response = StreamingResponse(\n                 status_code=message[\"status\"], content=body_stream()\n             )\n", "issue": "Raising Exceptions in sub-applications routes\n### Checklist\r\n\r\n- [X] The bug is reproducible against the latest release or `master`.\r\n- [X] There are no similar issues or pull requests to fix it yet.\r\n\r\n### Describe the bug\r\n\r\nLet's start with this PR: #1262\r\n\r\nIt's about preventing raise `anyio.ExceptionGroup` in views under a `BaseHTTPMiddleware`. PR resolve that problem with nonlocal variable that stores our exception. But in the case of sub-applications, it does not work. \r\n\r\nAs I can see (fyi I am not good at asyncio), in the case below, we reach and read a response before we raise an exception and store it to our nonlocal variable:\r\n\r\nfragment of `BaseHTTPMiddleware.__call__`\r\n```python\r\nasync def call_next(request: Request) -> Response:\r\n    app_exc: typing.Optional[Exception] = None\r\n    send_stream, recv_stream = anyio.create_memory_object_stream()\r\n\r\n    async def coro() -> None:\r\n        nonlocal app_exc\r\n\r\n        async with send_stream:\r\n            try:\r\n                task = await self.app(scope, request.receive, send_stream.send)\r\n            except Exception as exc:\r\n                app_exc = exc\r\n\r\n    task_group.start_soon(coro)\r\n\r\n    try:\r\n        message = await recv_stream.receive()\r\n    except anyio.EndOfStream:\r\n        if app_exc is not None:\r\n            raise app_exc\r\n        raise RuntimeError(\"No response returned.\")\r\n    \r\n    ...\r\n    response = StreamingResponse(\r\n        status_code=message[\"status\"], content=body_stream()\r\n    )\r\n    response.raw_headers = message[\"headers\"]\r\n    return response\r\n```\r\n\r\nin this moment: `except anyio.EndOfStream:` exception still no raised.\r\n\r\n### Steps to reproduce the bug\r\n\r\n```python\r\nimport httpx\r\nimport pytest\r\nfrom fastapi import FastAPI, APIRouter\r\nfrom starlette.middleware import Middleware\r\nfrom starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint\r\nfrom starlette.requests import Request\r\nfrom starlette.responses import Response\r\nfrom starlette.routing import Route\r\n\r\n\r\nclass SomeError(Exception):\r\n    pass\r\n\r\n\r\nclass SomeMiddleware(BaseHTTPMiddleware):\r\n    async def dispatch(\r\n        self, request: Request, call_next: RequestResponseEndpoint\r\n    ) -> Response:\r\n        return await call_next(request)\r\n\r\n# Drop (or use not BaseHTTPMiddleware based) middleware and test works fine\r\napp = FastAPI(middleware=[Middleware(SomeMiddleware), ])\r\n\r\n\r\nasync def simple_route(request: Request):\r\n    raise SomeError\r\n\r\n\r\nanother_router = APIRouter(\r\n    routes=[Route('/simple-route/', simple_route, methods=['GET'])]\r\n)\r\nsub_app = FastAPI()\r\nsub_app.include_router(another_router)\r\napp.router.mount(f'/api', sub_app)\r\n\r\n\r\n@pytest.mark.asyncio\r\nasync def test_simple_route():\r\n    async with httpx.AsyncClient(app=app) as client:\r\n        with pytest.raises(SomeError):\r\n            await client.get(\"http://testserver/api/simple-route/\")\r\n\r\n```\r\n\r\n### Expected behavior\r\n\r\nAn exception was raised and caught by pytest exception\r\n\r\n### Actual behavior\r\n\r\nAn exception wasn't raised\r\n\r\n### Debugging material\r\n\r\n_No response_\r\n\r\n### Environment\r\n\r\nmacOS Monterey 12.0.1, starlette 0.17.1, Python 3.9.9\r\n\r\n\r\n### Additional context\r\n\r\n_No response_\n", "before_files": [{"content": "import typing\n\nimport anyio\n\nfrom starlette.requests import Request\nfrom starlette.responses import Response, StreamingResponse\nfrom starlette.types import ASGIApp, Receive, Scope, Send\n\nRequestResponseEndpoint = typing.Callable[[Request], typing.Awaitable[Response]]\nDispatchFunction = typing.Callable[\n    [Request, RequestResponseEndpoint], typing.Awaitable[Response]\n]\n\n\nclass BaseHTTPMiddleware:\n    def __init__(self, app: ASGIApp, dispatch: DispatchFunction = None) -> None:\n        self.app = app\n        self.dispatch_func = self.dispatch if dispatch is None else dispatch\n\n    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n        if scope[\"type\"] != \"http\":\n            await self.app(scope, receive, send)\n            return\n\n        async def call_next(request: Request) -> Response:\n            app_exc: typing.Optional[Exception] = None\n            send_stream, recv_stream = anyio.create_memory_object_stream()\n\n            async def coro() -> None:\n                nonlocal app_exc\n\n                async with send_stream:\n                    try:\n                        await self.app(scope, request.receive, send_stream.send)\n                    except Exception as exc:\n                        app_exc = exc\n\n            task_group.start_soon(coro)\n\n            try:\n                message = await recv_stream.receive()\n            except anyio.EndOfStream:\n                if app_exc is not None:\n                    raise app_exc\n                raise RuntimeError(\"No response returned.\")\n\n            assert message[\"type\"] == \"http.response.start\"\n\n            async def body_stream() -> typing.AsyncGenerator[bytes, None]:\n                async with recv_stream:\n                    async for message in recv_stream:\n                        assert message[\"type\"] == \"http.response.body\"\n                        yield message.get(\"body\", b\"\")\n\n            response = StreamingResponse(\n                status_code=message[\"status\"], content=body_stream()\n            )\n            response.raw_headers = message[\"headers\"]\n            return response\n\n        async with anyio.create_task_group() as task_group:\n            request = Request(scope, receive=receive)\n            response = await self.dispatch_func(request, call_next)\n            await response(scope, receive, send)\n            task_group.cancel_scope.cancel()\n\n    async def dispatch(\n        self, request: Request, call_next: RequestResponseEndpoint\n    ) -> Response:\n        raise NotImplementedError()  # pragma: no cover\n", "path": "starlette/middleware/base.py"}], "after_files": [{"content": "import typing\n\nimport anyio\n\nfrom starlette.requests import Request\nfrom starlette.responses import Response, StreamingResponse\nfrom starlette.types import ASGIApp, Receive, Scope, Send\n\nRequestResponseEndpoint = typing.Callable[[Request], typing.Awaitable[Response]]\nDispatchFunction = typing.Callable[\n    [Request, RequestResponseEndpoint], typing.Awaitable[Response]\n]\n\n\nclass BaseHTTPMiddleware:\n    def __init__(self, app: ASGIApp, dispatch: DispatchFunction = None) -> None:\n        self.app = app\n        self.dispatch_func = self.dispatch if dispatch is None else dispatch\n\n    async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:\n        if scope[\"type\"] != \"http\":\n            await self.app(scope, receive, send)\n            return\n\n        async def call_next(request: Request) -> Response:\n            app_exc: typing.Optional[Exception] = None\n            send_stream, recv_stream = anyio.create_memory_object_stream()\n\n            async def coro() -> None:\n                nonlocal app_exc\n\n                async with send_stream:\n                    try:\n                        await self.app(scope, request.receive, send_stream.send)\n                    except Exception as exc:\n                        app_exc = exc\n\n            task_group.start_soon(coro)\n\n            try:\n                message = await recv_stream.receive()\n            except anyio.EndOfStream:\n                if app_exc is not None:\n                    raise app_exc\n                raise RuntimeError(\"No response returned.\")\n\n            assert message[\"type\"] == \"http.response.start\"\n\n            async def body_stream() -> typing.AsyncGenerator[bytes, None]:\n                async with recv_stream:\n                    async for message in recv_stream:\n                        assert message[\"type\"] == \"http.response.body\"\n                        yield message.get(\"body\", b\"\")\n\n                if app_exc is not None:\n                    raise app_exc\n\n            response = StreamingResponse(\n                status_code=message[\"status\"], content=body_stream()\n            )\n            response.raw_headers = message[\"headers\"]\n            return response\n\n        async with anyio.create_task_group() as task_group:\n            request = Request(scope, receive=receive)\n            response = await self.dispatch_func(request, call_next)\n            await response(scope, receive, send)\n            task_group.cancel_scope.cancel()\n\n    async def dispatch(\n        self, request: Request, call_next: RequestResponseEndpoint\n    ) -> Response:\n        raise NotImplementedError()  # pragma: no cover\n", "path": "starlette/middleware/base.py"}]}