Skip to content

Commit 247b9c4

Browse files
authored
feat(backend): improve status and error contract consistency (#406)
## Summary This PR standardizes backend error handling so malformed or invalid client queries return predictable HTTP responses instead of generic `500 Internal Server Error` results. It aligns runtime status mapping, structured error payloads, and OpenAPI documentation to provide a clearer and more reliable contract for API consumers. --- ## Related Issue Fixes #405 --- ## Notes This is a backend API contract improvement focused on better HTTP semantics, stronger documentation, and safer client-facing error handling.
1 parent 66e6651 commit 247b9c4

3 files changed

Lines changed: 8 additions & 4 deletions

File tree

app/_types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ class SearchResponseDebug(BaseModel):
9090
class SearchResponseError(BaseModel):
9191
title: str
9292
description: str | None = None
93+
status: int | None = None
9394

9495

9596
class ErrorSearchResponse(BaseModel):

app/api.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
PostSearchParameters,
1919
SearchResponse,
2020
SuccessSearchResponse,
21+
ErrorSearchResponse,
2122
)
2223
from app.config import settings
2324
from app.postprocessing import process_taxonomy_completion_response
@@ -101,12 +102,14 @@ def get_document(
101102
def status_for_response(result: SearchResponse):
102103
if isinstance(result, SuccessSearchResponse):
103104
return status.HTTP_200_OK
105+
elif isinstance(result, ErrorSearchResponse) and result.errors:
106+
# returns the status of the first error
107+
return result.errors[0].status or status.HTTP_500_INTERNAL_SERVER_ERROR
104108
else:
105-
# TODO: should we refine that ?
106109
return status.HTTP_500_INTERNAL_SERVER_ERROR
107110

108111

109-
@app.post("/search")
112+
@app.post("/search", responses={400: {"model": ErrorSearchResponse}, 500: {"model": ErrorSearchResponse}})
110113
def search(
111114
response: Response, search_parameters: Annotated[PostSearchParameters, Body()]
112115
) -> SearchResponse:
@@ -121,7 +124,7 @@ def search(
121124
return result
122125

123126

124-
@app.get("/search")
127+
@app.get("/search", responses={400: {"model": ErrorSearchResponse}, 500: {"model": ErrorSearchResponse}})
125128
def search_get(
126129
response: Response, search_parameters: Annotated[GetSearchParameters, Query()]
127130
) -> SearchResponse:

app/search.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def search(
9292
except QueryCheckError as e:
9393
return ErrorSearchResponse(
9494
debug=SearchResponseDebug(),
95-
errors=[SearchResponseError(title="QueryCheckError", description=str(e))],
95+
errors=[SearchResponseError(title="QueryCheckError", description=str(e), status=400)],
9696
)
9797
(
9898
logger.debug(

0 commit comments

Comments
 (0)