|
|
|
@ -6,7 +6,23 @@ from fastapi.testclient import TestClient |
|
|
|
app = FastAPI() |
|
|
|
|
|
|
|
|
|
|
|
async def get_username_reraises(): |
|
|
|
def get_username_reraises(): |
|
|
|
try: |
|
|
|
with open("/nonexistent/path.txt") as f: |
|
|
|
yield f.read() # pragma: no cover |
|
|
|
except OSError as ex: |
|
|
|
raise RuntimeError("File read error") from ex |
|
|
|
|
|
|
|
|
|
|
|
def get_username_doesnt_reraise(): |
|
|
|
try: |
|
|
|
with open("/nonexistent/path.txt") as f: |
|
|
|
yield f.read() # pragma: no cover |
|
|
|
except OSError: |
|
|
|
print("Didn't re-raise") |
|
|
|
|
|
|
|
|
|
|
|
async def get_username_reraises_async(): |
|
|
|
try: |
|
|
|
async with await open_file("/nonexistent/path.txt", "r") as f: |
|
|
|
yield await f.read() # pragma: no cover |
|
|
|
@ -14,7 +30,7 @@ async def get_username_reraises(): |
|
|
|
raise RuntimeError("File read error") from ex |
|
|
|
|
|
|
|
|
|
|
|
async def get_username_doesnt_reraise(): |
|
|
|
async def get_username_doesnt_reraise_async(): |
|
|
|
try: |
|
|
|
async with await open_file("/nonexistent/path.txt", "r") as f: |
|
|
|
yield await f.read() # pragma: no cover |
|
|
|
@ -32,22 +48,42 @@ def get_me_doesnt_reraise(username: str = Depends(get_username_doesnt_reraise)): |
|
|
|
return username # pragma: no cover |
|
|
|
|
|
|
|
|
|
|
|
@app.get("/reraises-async") |
|
|
|
def get_me_reraises_async(username: str = Depends(get_username_reraises_async)): |
|
|
|
return username # pragma: no cover |
|
|
|
|
|
|
|
|
|
|
|
@app.get("/doesnt-reraise-async") |
|
|
|
def get_me_doesnt_reraise_async( |
|
|
|
username: str = Depends(get_username_doesnt_reraise_async), |
|
|
|
): |
|
|
|
return username # pragma: no cover |
|
|
|
|
|
|
|
|
|
|
|
client = TestClient(app) |
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.anyio |
|
|
|
def test_runtime_error_reraises(): |
|
|
|
@pytest.mark.parametrize("path", ["/reraises", "/reraises-async"]) |
|
|
|
def test_runtime_error_reraises(path: str): |
|
|
|
with pytest.raises(RuntimeError) as exc_info: |
|
|
|
client.get("/reraises") |
|
|
|
client.get(path) |
|
|
|
assert str(exc_info.value) == "File read error" |
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.anyio |
|
|
|
def test_runtime_error_doesnt_reraise(): |
|
|
|
@pytest.mark.parametrize( |
|
|
|
("path", "fn_name"), |
|
|
|
[ |
|
|
|
("/doesnt-reraise", "get_username_doesnt_reraise"), |
|
|
|
("/doesnt-reraise-async", "get_username_doesnt_reraise_async"), |
|
|
|
], |
|
|
|
) |
|
|
|
def test_runtime_error_doesnt_reraise(path: str, fn_name: str): |
|
|
|
with pytest.raises(RuntimeError) as exc_info: |
|
|
|
client.get("/doesnt-reraise") |
|
|
|
client.get(path) |
|
|
|
assert str(exc_info.value).startswith( |
|
|
|
"Dependency get_username_doesnt_reraise raised: generator didn't yield. " |
|
|
|
f"Dependency {fn_name} raised: generator didn't yield. " |
|
|
|
"There's a high chance that this is a dependency with yield that catches an " |
|
|
|
"exception using except, but doesn't raise the exception again." |
|
|
|
) |
|
|
|
|