Repository: encode/uvicorn

Issue:
Unexcepted behavior while reloading
### Initial Checks


- [x] I'm aware that if I created this issue without a discussion, it may be closed without a response.



### Description

Hello, in the uvicorn version **0.29.0** which is the latest version on 3/30/2024 when I wrote my code updated it, and saved the changes, I saw unexpected information in the terminal that I mentioned below in the code example, where this error is not occurring in the previous versions of uvicorn like:0.27.1

### Example Code

```Python
INFO:     Shutting down
INFO:     Waiting for application shutdown.
INFO:     Application shutdown complete.
INFO:     Finished server process [3608]
Process SpawnProcess-2:
Traceback (most recent call last):
  File "C:\Users\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 314, in _bootstrap
    self.run()
  File "C:\Users\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\backend\env\lib\site-packages\uvicorn\_subprocess.py", line 78, in subprocess_started
    target(sockets=sockets)
  File "C:\-backend\env\lib\site-packages\uvicorn\server.py", line 65, in run
    return asyncio.run(self.serve(sockets=sockets))
  File "C:\Users\AppData\Local\Programs\Python\Python310\lib\asyncio\runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "C:\Users\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 633, in run_until_complete
    self.run_forever()
  File "C:\Users\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 600, in run_forever
    self._run_once()
  File "C:\Users\AppData\Local\Programs\Python\Python310\lib\asyncio\base_events.py", line 1896, in _run_once
    handle._run()
  File "C:\UsersAppData\Local\Programs\Python\Python310\lib\asyncio\events.py", line 80, in _run
    self._context.run(self._callback, *self._args)
  File "C:\-backend\env\lib\site-packages\uvicorn\server.py", line 68, in serve
    with self.capture_signals():
  File "C:\Users\AppData\Local\Programs\Python\Python310\lib\contextlib.py", line 142, in __exit__
    next(self.gen)
  File "C:\backend\env\lib\site-packages\uvicorn\server.py", line 328, in capture_signals
    signal.raise_signal(captured_signal)
KeyboardInterrupt
INFO:     Started server process [8232]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
```


### Python, Uvicorn & OS Version

```Text
Windows11 Enterprise 64-bit (10.0, Build 22000)
Python 3.10.6
uvicorn 0.29.0
```


<!-- POLAR PLEDGE BADGE START -->
> [!IMPORTANT]
> - We're using [Polar.sh](https://polar.sh/encode) so you can upvote and help fund this issue.
> - We receive the funding once the issue is completed & confirmed by you.
> - Thank you in advance for helping prioritize & fund our backlog.

<a href="https://polar.sh/encode/uvicorn/issues/2294">
<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://polar.sh/api/github/encode/uvicorn/issues/2294/pledge.svg?darkmode=1">
  <img alt="Fund with Polar" src="https://polar.sh/api/github/encode/uvicorn/issues/2294/pledge.svg">
</picture>
</a>
<!-- POLAR PLEDGE BADGE END -->



Discussion:
Exactly I have been experiencing this since whenever I restart my FastAPI application, it doesnt restart gracefully but logs this exact message like yours

I need a computer with Windows.
Am having the same error and am using Windows 

> Exactly I have been experiencing this since whenever I restart my FastAPI application, it doesnt restart gracefully but logs this exact message like yours

Yes exactly, and its just appears in the latest version of uvicorn I donwgraded mmy uvicorn version to 0.27.1 and its totally fine 
Just started learning and experimenting since yesterday using FastAPI for the first time. I have same problem.

Every Ctrl+S or any file save in the repo (folder being watched for changes) reloads the app with no problem, but the terminal is cluttered with this exception every single time.

Btw the reload of app is being done on file save even when there were no changes the file (which I didnt experience with saving a file without changes in Angular app for example)
> Just started learning and experimenting since yesterday using FastAPI for the first time. I have same problem.
> 
> 
> 
> Every Ctrl+S or any file save in the repo (folder being watched for changes) reloads the app with no problem, but the terminal is cluttered with this exception every single time.
> 
> 
> 
> Btw the reload of app is being done on file save even when there were no changes the file (which I didnt experience with saving a file without changes in Angular app for example)

Hi, i had the same problem.
for now,you can use the previous version of uvicorn and solve the problem you can use version : **0.27.1**
Just to add my me too here, me too.
Windows machine, PyEnv en Poetry, tried 3 python versions 3.9/3.11/3.12 all same issue.
Rolling back to uvicorn 0.27.1 fixed the issue with --reload
+1
Maybe a clue is that when I run it in command it behaves better than running it in powershell.
The error occurs only in `0.29.0`, but `0.28.1` just works fine.

Resolving patch:
diff --git a/uvicorn/_subprocess.py b/uvicorn/_subprocess.py
--- a/uvicorn/_subprocess.py
+++ b/uvicorn/_subprocess.py
@@ -75,5 +75,10 @@ def subprocess_started(
     # Logging needs to be setup again for each child.
     config.configure_logging()
 
-    # Now we can call into `Server.run(sockets=sockets)`
-    target(sockets=sockets)
+    try:
+        # Now we can call into `Server.run(sockets=sockets)`
+        target(sockets=sockets)
+    except KeyboardInterrupt:  # pragma: no cover
+        # supress the exception to avoid a traceback from subprocess.Popen
+        # the parent already expects us to end, so no vital information is lost
+        pass
diff --git a/uvicorn/main.py b/uvicorn/main.py
--- a/uvicorn/main.py
+++ b/uvicorn/main.py
@@ -566,16 +566,18 @@ def run(
         logger.warning("You must pass the application as an import string to enable 'reload' or " "'workers'.")
         sys.exit(1)
 
-    if config.should_reload:
-        sock = config.bind_socket()
-        ChangeReload(config, target=server.run, sockets=[sock]).run()
-    elif config.workers > 1:
-        sock = config.bind_socket()
-        Multiprocess(config, target=server.run, sockets=[sock]).run()
-    else:
-        server.run()
-    if config.uds and os.path.exists(config.uds):
-        os.remove(config.uds)  # pragma: py-win32
+    try:
+        if config.should_reload:
+            sock = config.bind_socket()
+            ChangeReload(config, target=server.run, sockets=[sock]).run()
+        elif config.workers > 1:
+            sock = config.bind_socket()
+            Multiprocess(config, target=server.run, sockets=[sock]).run()
+        else:
+            server.run()
+    finally:
+        if config.uds and os.path.exists(config.uds):
+            os.remove(config.uds)  # pragma: py-win32
 
     if not server.started and not config.should_reload and config.workers == 1:
         sys.exit(STARTUP_FAILURE)


Test patch: