Raise HTTPException not being called

Question:

I have the following code:

@events_router.delete("/events/{event_id}", status_code=204)
def delete_event(*, event_id: int) -> None:
    for event in EVENTS:
        if event['id'] == event_id:
            del EVENTS[event_id-1]
            print("event id = " + str(event_id) + " deleted!")
            break
        raise HTTPException(
            status_code=404,
            detail=f"Event with ID {event_id} not found"
        )

If I add an event and delete it by sending the correct id i.e. 1 the item gets deleted fine, however if I try to delete any item that is not the correct id then it gives a 204 status code rather than 404 with the message detail, see below:

INFO:     Uvicorn running on http://0.0.0.0:8001 (Press CTRL+C to quit)
INFO:     127.0.0.1:64831 - "GET /docs HTTP/1.1" 200 OK
INFO:     127.0.0.1:64831 - "GET /openapi.json HTTP/1.1" 200 OK
INFO:     127.0.0.1:64832 - "POST /events/ HTTP/1.1" 201 Created
event id = 1 deleted!
INFO:     127.0.0.1:65016 - "DELETE /events/2 HTTP/1.1" 204 No Content
INFO:     127.0.0.1:65054 - "DELETE /events/5 HTTP/1.1" 204 No Content
INFO:     127.0.0.1:65076 - "DELETE /events/0 HTTP/1.1" 204 No Content
INFO:     127.0.0.1:65114 - "DELETE /events/3 HTTP/1.1" 204 No Content

Why is the HTTPException not being raised here, if the id is not correct?

Thank you for any help!

Asked By: Steve Malek

||

Answers:

You missplaced your raise statement. Now it’s inside the loop and because there are no events it doesn’t even go inside.

It should be:

@events_router.delete("/events/{event_id}", status_code=204)
def delete_event(*, event_id: int) -> None:
    for event in EVENTS:
        if event['id'] == event_id:
            del EVENTS[event_id-1]
            print("event id = " + str(event_id) + " deleted!")
            break
    else:
        raise HTTPException(
            status_code=404,
            detail=f"Event with ID {event_id} not found"
        )

And to simplify the code, consider to create event mapping:

EVENT_BY_ID = {event["id"]: event for event in EVENTS}

@events_router.delete("/events/{event_id}", status_code=204)
def delete_event(*, event_id: int) -> None:
    if event_id in EVENT_BY_ID:
        ...
    else:
        raise
Answered By: kosciej16
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.