Enhance Error Handling for Invalid Response Type in Golden SQL Addition #443
Description
Issue Description:
Currently, when attempting to add golden SQLs for few-shot examples with an incorrect database connection ID, the application throws a lengthy error traceback. To improve user experience and error handling, this issue proposes implementing exception handling in the init.py file of the FastAPI module.
Error we are currently getting as response:
Traceback (most recent call last):
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/errors.py", line 162, in __call__
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
raise exc
File "/usr/local/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
await self.app(scope, receive, sender)
File "/usr/local/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 20, in __call__
raise e
File "/usr/local/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 17, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 718, in __call__
await route.handle(scope, receive, send)
File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 276, in handle
await self.app(scope, receive, send)
File "/usr/local/lib/python3.11/site-packages/starlette/routing.py", line 66, in app
response = await func(request)
^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/fastapi/routing.py", line 241, in app
raw_response = await run_endpoint_function(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/fastapi/routing.py", line 169, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/starlette/concurrency.py", line 41, in run_in_threadpool
return await anyio.to_thread.run_sync(func, *args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/anyio/to_thread.py", line 56, in run_sync
return await get_async_backend().run_sync_in_worker_thread(
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 2144, in run_sync_in_worker_thread
return await future
^^^^^^^^^^^^
File "/usr/local/lib/python3.11/site-packages/anyio/_backends/_asyncio.py", line 851, in run
result = context.run(func, *args)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/app/dataherald/server/fastapi/__init__.py", line 536, in add_golden_sqls
golden_sqls_as_dicts = [record.dict() for record in created_records]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: 'JSONResponse' object is not iterable
Proposed Solution:
- Update
add_golden_sqls
method in dataherald\server\fastapi\ _ init _.py file:
def add_golden_sqls(
self, golden_sqls: List[GoldenSQLRequest]
) -> List[GoldenSQLResponse]:
created_records = self._api.add_golden_sqls(golden_sqls)
if not isinstance(created_records, list):
response_body = created_records.body
response_data = json.loads(response_body)
raise HTTPException(status_code=404, detail=response_data)
# Return a JSONResponse with status code 201 and the location header.
golden_sqls_as_dicts = [record.dict() for record in created_records]
return JSONResponse(
content=golden_sqls_as_dicts, status_code=status.HTTP_201_CREATED
)
This code block checks if created_records is not a list, indicating an unexpected response type. If so, it extracts relevant information from the response body, converts it to JSON format, and raises an HTTPException with a status code of 404 and detailed error information.
Expected Outcome:
By implementing exception handling for invalid response types, the application will provide more informative and user-friendly error messages when encountering issues related to incorrect database connection IDs.
Response after proposed solution is implemented:
{
"detail": {
"error_code": "database_connection_not_found",
"message": "Database connection not found, 6603a7675723a587a67e590e",
"description": null,
"detail": {
"items": [
{
"db_connection_id": "6603a7675723a587a17e590e",
"prompt_text": "Random prompt",
"sql": "sql query...................",
"metadata": {}
},
{
"db_connection_id": "6603a7675723a587a67e590e",
"prompt_text": "Random prompt",
"sql": "sql query ..................",
"metadata": {}
}
]
}
}
}
Preliminary Evaluation:
I've carried out initial assessments of the suggested modifications, tested the proposed solution using Docker as suggested in the CONTRIBUTING.md.
At present, I haven't initiated a pull request, opting instead to solicit feedback on the proposed solution as I believe there may be more efficient methods to achieve this.