From 99e3f8386cbe8f921f00415bc85df55fd39dda6a Mon Sep 17 00:00:00 2001 From: Sierra Taylor Moxon Date: Mon, 12 Aug 2024 15:45:56 -0700 Subject: [PATCH] add global value error handling --- app/main.py | 19 ++++++++++++++-- app/routers/pathway_widget.py | 3 +++ tests/unit/test_global_exception_handling.py | 24 ++++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 tests/unit/test_global_exception_handling.py diff --git a/app/main.py b/app/main.py index 32f40b7..1816f65 100644 --- a/app/main.py +++ b/app/main.py @@ -1,9 +1,10 @@ """main application entry point.""" import uvicorn -from fastapi import FastAPI, HTTPException, Request +from fastapi import FastAPI, Request from fastapi.middleware.cors import CORSMiddleware - +from fastapi.responses import JSONResponse +import requests from app.middleware.logging_middleware import LoggingMiddleware from app.routers import ( bioentity, @@ -18,6 +19,9 @@ slimmer, users_and_groups, ) +import logging + +logger = logging.getLogger("uvicorn.error") app = FastAPI( title="GO API", @@ -54,6 +58,16 @@ ) +# Global exception handler for ValueErrors +@app.exception_handler(ValueError) +async def value_error_handler(request: Request, exc: ValueError): + logger.error(f"Value error occurred: {exc}") + return JSONResponse( + status_code=400, + content={"message": f"Value error occurred: {exc}"} + ) + + @app.exception_handler(Exception) async def general_exception_handler(request: Request, exc: Exception): return JSONResponse( @@ -61,6 +75,7 @@ async def general_exception_handler(request: Request, exc: Exception): content={"message": "An unexpected error occurred. Please try again later."}, ) + @app.exception_handler(requests.exceptions.RequestException) async def requests_exception_handler(request: Request, exc: requests.exceptions.RequestException): return JSONResponse( diff --git a/app/routers/pathway_widget.py b/app/routers/pathway_widget.py index 5ab0a4a..68f8684 100644 --- a/app/routers/pathway_widget.py +++ b/app/routers/pathway_widget.py @@ -39,6 +39,9 @@ async def get_gocams_by_geneproduct_id( (e.g. MGI:3588192, ZFIN:ZDB-GENE-000403-1). """ + if ":" not in id: + raise ValueError("Invalid CURIE format") + if id.startswith("MGI:MGI:"): id = id.replace("MGI:MGI:", "MGI:") diff --git a/tests/unit/test_global_exception_handling.py b/tests/unit/test_global_exception_handling.py new file mode 100644 index 0000000..a43b53a --- /dev/null +++ b/tests/unit/test_global_exception_handling.py @@ -0,0 +1,24 @@ +from fastapi.testclient import TestClient +from app.main import app + +test_client = TestClient(app) + + +def test_value_error_handler(): + # Simulate an endpoint that raises a ValueError (e.g., by sending an invalid CURIE) + response = test_client.get("/api/ontol/labeler?id=@base:invalid") + + # Verify that the global exception handler for ValueErrors, rewrites as an internal server error code. + assert response.status_code == 400 + response = test_client.get(f"/api/gp/P05067/models") + + +def test_value_error_curie(): + response = test_client.get(f"/api/gp/P05067/models") + assert response.status_code == 400 + assert response.json() == {"message": "Value error occurred: Invalid CURIE format"} + + +def test_ncbi_taxon_error_handling(): + response = test_client.get("/api/taxon/NCBITaxon%3A4896/models") + assert response.status_code == 200