From 2217de841ee61aff02779b34837b0472d99ec3e0 Mon Sep 17 00:00:00 2001 From: garciam Date: Thu, 8 Aug 2024 18:02:24 +0200 Subject: [PATCH 1/2] improve the way the api handles the errors --- cdsobs/api_rest/endpoints.py | 30 ++++++++++++++++++++++-------- tests/retrieve/test_adaptor.py | 4 ++-- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/cdsobs/api_rest/endpoints.py b/cdsobs/api_rest/endpoints.py index d27edf0..7b7d949 100644 --- a/cdsobs/api_rest/endpoints.py +++ b/cdsobs/api_rest/endpoints.py @@ -48,6 +48,18 @@ def session_gen() -> Iterator[HttpAPISession]: session.catalogue_session.close() +def make_http_exception( + status_code: int, message: str, traceback: str | None = None +) -> HTTPException: + detail = dict(message="Error: Observations API failed.") + if traceback is not None: + detail["traceback"] = traceback + http_exception = HTTPException( + status_code=status_code, detail=dict(message=message, traceback=traceback) + ) + return http_exception + + @router.post("/get_object_urls_and_check_size") def get_object_urls_and_check_size( retrieve_payload: RetrievePayload, @@ -59,10 +71,12 @@ def get_object_urls_and_check_size( catalogue_repository = CatalogueRepository(session.catalogue_session) entries = _get_catalogue_entries(catalogue_repository, retrieve_args) except DataNotFoundException as e: - raise HTTPException(status_code=500, detail=f"Error: {e}") + raise make_http_exception(status_code=500, message=f"Error: {e}") except Exception as e: - raise HTTPException( - status_code=500, detail=f"Error: Observations API failed: {e}" + raise make_http_exception( + status_code=500, + message=f"Error: Observations API failed: {e}", + traceback=repr(e), ) s3client = S3Client.from_config(session.cdsobs_config.s3config) try: @@ -70,10 +84,10 @@ def get_object_urls_and_check_size( entries, retrieve_args, retrieve_payload.config.size_limit, s3client.base ) except SizeError as e: - raise HTTPException(status_code=500, detail=f"Error: {e}") + raise HTTPException(status_code=500, detail=dict(message=f"Error: {e}")) except Exception as e: - raise HTTPException( - status_code=500, detail=f"Error: Observations API failed: {e}" + raise make_http_exception( + status_code=500, message="Error: Observations API failed", traceback=repr(e) ) return object_urls @@ -100,8 +114,8 @@ def get_dataset_service_definition(dataset: str) -> ServiceDefinition: try: return get_service_definition(dataset) except FileNotFoundError: - raise HTTPException( - status_code=404, detail=f"Service definition not found for {dataset=}" + raise make_http_exception( + status_code=404, message=f"Service definition not found for {dataset=}" ) diff --git a/tests/retrieve/test_adaptor.py b/tests/retrieve/test_adaptor.py index 9af1f6c..33f9c2e 100644 --- a/tests/retrieve/test_adaptor.py +++ b/tests/retrieve/test_adaptor.py @@ -44,7 +44,7 @@ def test_adaptor(tmp_path): assert xarray.open_dataset(tempfile).observation_id.size > 0 -@pytest.mark.skip("By hand only.") +# @pytest.mark.skip("By hand only.") def test_adaptor_uscrn(tmp_path): """Full test with a local instance of the HTTP API.""" from cads_adaptors import ObservationsAdaptor @@ -71,7 +71,7 @@ def test_adaptor_uscrn(tmp_path): test_adaptor_config = { "entry_point": "cads_adaptors:ObservationsAdaptor", "collection_id": "insitu-observations-near-surface-temperature-us-climate-reference-network", - "obs_api_url": "http://obscatalogue.cads-obs.compute.cci2.ecmwf.int", + "obs_api_url": "http://localhost:8000", "mapping": { "remap": { "time_aggregation": { From c9d42c793289eb86864062a78d94eb6d28f894cf Mon Sep 17 00:00:00 2001 From: garciam Date: Thu, 8 Aug 2024 18:02:50 +0200 Subject: [PATCH 2/2] disable test --- tests/retrieve/test_adaptor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/retrieve/test_adaptor.py b/tests/retrieve/test_adaptor.py index 33f9c2e..165986b 100644 --- a/tests/retrieve/test_adaptor.py +++ b/tests/retrieve/test_adaptor.py @@ -44,7 +44,7 @@ def test_adaptor(tmp_path): assert xarray.open_dataset(tempfile).observation_id.size > 0 -# @pytest.mark.skip("By hand only.") +@pytest.mark.skip("By hand only.") def test_adaptor_uscrn(tmp_path): """Full test with a local instance of the HTTP API.""" from cads_adaptors import ObservationsAdaptor