Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connexion/Uvicorn silently swallowing exceptions at startup #1693

Closed
SpudInNZ opened this issue Apr 24, 2023 · 1 comment
Closed

Connexion/Uvicorn silently swallowing exceptions at startup #1693

SpudInNZ opened this issue Apr 24, 2023 · 1 comment
Labels

Comments

@SpudInNZ
Copy link

SpudInNZ commented Apr 24, 2023

Description

I have an issue in my code that means the server cannot start. Instead of seeing the error in the logs and have the server exit, Uvicorn/Connexion is swallowing the exception and erroneously displaying "ASGI 'lifespan' protocol appears unsupported." instead. It does this whether or not I specify lifespan= in the init call.

Expected behaviour

The server should exit with an error message and the exception text if it fails to start.

Actual behaviour

Uvicorn appears to still be running even though the webserver failed to start/exited

Steps to reproduce

In my case the error was in a call to a decorator on an API endpoint handler, probably easy to reproduce something similar.

@fb_api(required_scopes=[], required_permissions=[], no_cache=True, audit=False)
async def get_health(*, request: Request):
 [...]

This endpoint is referenced in the swagger spec.

Additional info:

The runtime error I get in my code is:

TypeError("fb_api() got an unexpected keyword argument 'required_permissions'")

But the logging output is:

webapi_1          | INFO:     Started server process [7]
webapi_1          | INFO:     Waiting for application startup.
webapi_1          | INFO:     ASGI 'lifespan' protocol appears unsupported.
webapi_1          | INFO:     Application startup complete.
webapi_1          | INFO:     Uvicorn running on http://0.0.0.0:8082 (Press CTRL+C to quit)


100% a simple bug in my code. I can see this by placing a breakpoint in the exception handler uvicorn.lifespan.on.py:

    async def main(self) -> None:
        try:
            app = self.config.loaded_app
            scope: LifespanScope = {  # type: ignore[typeddict-item]
                "type": "lifespan",
                "asgi": {"version": self.config.asgi_version, "spec_version": "2.0"},
                "state": self.state,
            }
            await app(scope, self.receive, self.send)
        except BaseException as exc:
            self.asgi = None
            self.error_occured = True
            if self.startup_failed or self.shutdown_failed:
                return
            if self.config.lifespan == "auto":
                msg = "ASGI 'lifespan' protocol appears unsupported."
                self.logger.info(msg)
            else:
                msg = "Exception in 'lifespan' protocol\n"
                self.logger.error(msg, exc_info=exc)

Ideally this block of code would be executed:

            if self.startup_failed or self.shutdown_failed:
                return

But instead

            if self.config.lifespan == "auto":
                msg = "ASGI 'lifespan' protocol appears unsupported."
                self.logger.info(msg)

is executed. Even then, the exception message would be swallowed. It seems like there should be an exception handler further up the stack catching the exception, printing the message and setting self.startup_failed, but I don't really know.

Output of the commands:

  • python --version Python 3.11.3
  • pip show connexion | grep "^Version\:" Version: 3.0.0a5
@Ruwann Ruwann added the bug label May 5, 2023
@RobbeSneyders
Copy link
Member

I believe this might be fixed by #1711 and #1754. Feel free to reopen with a reproducible example if you still run into this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants