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

Force lambda failure #555

Open
ahmadmaj opened this issue Dec 3, 2024 · 3 comments · May be fixed by #558
Open

Force lambda failure #555

ahmadmaj opened this issue Dec 3, 2024 · 3 comments · May be fixed by #558

Comments

@ahmadmaj
Copy link

ahmadmaj commented Dec 3, 2024

Hi, thanks for this great repo which makes it super easy to deploy web applications to AWS lambdas.
I am using this adapter on top of uvicorn and FastAPI. My problem is that it is almost impossible to make my lambda fail on some specific cases that I want my lambda to fail, instead of returning an http response with status code 500 (or whatever another status code).
Uvicorn will just catch any exception that comes from the application, and will return a response 500 with internal server error message, and there is no way to disable that behaviour.
The only way I could force the lambda to fail is by doing os._exit(1) in my code, which is not the best solution because the app won't get terminated correctly. In addition, once this workaround is done, the next lambda invocation will take around 30 secs to get processed (normally it takes ~5 seconds to run with cold start).
My question and suggestion is to add new environment variable which has the status code in which we want the lambda to fail, and if the adapter gets that status code in the response, it will make the lambda fail instead of returning the response as is.

Thanks!

@Minitour
Copy link

Minitour commented Dec 3, 2024

Related to #537

@Minitour
Copy link

Minitour commented Dec 3, 2024

Not sure about other frameworks, but for FastAPI and uvicorn you can create a middleware that intercepts exceptions and changes the HTTP status code to something invalid (e.g., 1). This will cause uvicorn to raise an unhandled KeyError which ultimately result an an error that propagates all the way to the adapter as can be seen on line 342:

let mut app_response = self.client.request(request).await?;

This will make the adapter crash, which will make the lambda function crash respectively.

from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.responses import Response


class DropConnectionMiddleware(BaseHTTPMiddleware):

    async def dispatch(self, request: Request, call_next):
        try:
            response = await call_next(request)
            return response
        except SpecificException:
            response = Response()
            response.status_code = 1 # <-- This gets the job done
            return response


class SpecificException(Exception):
    pass


app = FastAPI()
app.add_middleware(DropConnectionMiddleware)

counter = 1


@app.get("/error")
async def cause_error():
    raise SpecificException()


@app.get("/ok")
async def server_error():
    global counter
    response = Response(status_code=200, content=f"Counter is {counter}")
    counter += 1
    return response


if __name__ == '__main__':
    import uvicorn

    uvicorn.run(app)

@ahmadmaj
Copy link
Author

ahmadmaj commented Dec 4, 2024

@Minitour Thanks for this, it does the job!
Still, adding the support at the adapter change is appreciated. It sure will help for different frameworks or if the behavior will be changed on uvicorn.

@bnusunny bnusunny linked a pull request Dec 16, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants