Skip to content

Commit

Permalink
Finish redesign of API error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
bkis committed Feb 4, 2024
1 parent f0735c2 commit 371d1ea
Show file tree
Hide file tree
Showing 11 changed files with 1,039 additions and 230 deletions.
713 changes: 634 additions & 79 deletions Tekst-API/openapi.json

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions Tekst-API/tekst/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@ def error_instance(
msg="Cannot publish an unproposed resource",
)

E_400_RESOURCE_PROPOSE_PUBLIC = error_instance(
status_code=status.HTTP_400_BAD_REQUEST,
key="resourceProposePublic",
msg="Cannot propose a published resource",
)

E_400_RESOUCE_VERSION_PUBLISH = error_instance(
status_code=status.HTTP_400_BAD_REQUEST,
key="resourceVersionPublish",
Expand Down Expand Up @@ -242,10 +248,10 @@ def error_instance(
msg="Referenced resource type in updates doesn't match the one in target content",
)

E_400_LOCATION_INVALID_TEXT = error_instance(
E_400_INVALID_TEXT = error_instance(
status_code=status.HTTP_400_BAD_REQUEST,
key="locationInvalidText",
msg="Text ID in location doesn't reference an existing text",
key="referencedInvalidText",
msg="Text ID in in request data doesn't reference an existing text",
)

E_400_INVALID_LEVEL = error_instance(
Expand Down
14 changes: 6 additions & 8 deletions Tekst-API/tekst/routers/contents.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,12 @@
"",
response_model=AnyContentReadBody,
status_code=status.HTTP_201_CREATED,
responses={
errors.responses(
[
errors.E_403_FORBIDDEN,
errors.E_409_CONTENT_CONFLICT,
]
)
},
responses=errors.responses(
[
errors.E_403_FORBIDDEN,
errors.E_409_CONTENT_CONFLICT,
]
),
)
async def create_content(
content: AnyContentCreateBody, user: UserDep
Expand Down
9 changes: 4 additions & 5 deletions Tekst-API/tekst/routers/locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

from beanie import PydanticObjectId
from beanie.operators import And, In, NotIn
from fastapi import APIRouter, HTTPException, Path, Query, status
from fastapi import APIRouter, Path, Query, status

from tekst import errors
from tekst.auth import SuperuserDep
from tekst.logging import log
from tekst.models.content import ContentBaseDocument
from tekst.models.location import (
DeleteLocationResult,
Expand All @@ -14,7 +14,6 @@
LocationRead,
LocationUpdate,
)
from tekst import errors
from tekst.models.text import (
MoveLocationRequestBody,
TextDocument,
Expand All @@ -36,7 +35,7 @@
status_code=status.HTTP_201_CREATED,
responses=errors.responses(
[
errors.E_400_LOCATION_INVALID_TEXT,
errors.E_400_INVALID_TEXT,
errors.E_400_INVALID_LEVEL,
]
),
Expand All @@ -49,7 +48,7 @@ async def create_location(su: SuperuserDep, location: LocationCreate) -> Locatio
# find text the location belongs to
text = await TextDocument.find_one(TextDocument.id == location.text_id)
if not text:
raise errors.E_400_LOCATION_INVALID_TEXT
raise errors.E_400_INVALID_TEXT
# check if level is valid
if not location.level < len(text.levels):
raise errors.E_400_INVALID_LEVEL
Expand Down
1 change: 1 addition & 0 deletions Tekst-API/tekst/routers/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from beanie import PydanticObjectId
from beanie.operators import NotIn, Or, Text
from fastapi import APIRouter, Depends, Path, Query, status

from tekst import errors
from tekst.auth import (
OptionalUserDep,
Expand Down
8 changes: 6 additions & 2 deletions Tekst-API/tekst/routers/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ async def create_resource(
# check text integrity
text = await TextDocument.get(resource.text_id)
if not text:
raise errors.E_404_TEXT_NOT_FOUND
raise errors.E_400_INVALID_TEXT
if resource.level > len(text.levels) - 1:
raise errors.E_400_RESOURCE_INVALID_LEVEL

Expand Down Expand Up @@ -469,8 +469,10 @@ async def propose_resource(
raise errors.E_404_RESOURCE_NOT_FOUND
if not user.is_superuser and user.id != resource_doc.owner_id:
raise errors.E_403_FORBIDDEN
if resource_doc.public:
if resource_doc.proposed:
return await preprocess_resource_read(resource_doc, user)
if resource_doc.public:
raise errors.E_400_RESOURCE_PROPOSE_PUBLIC
if resource_doc.original_id:
raise errors.E_400_RESOURCE_VERSION_PROPOSE
# all fine, propose resource
Expand Down Expand Up @@ -531,6 +533,8 @@ async def publish_resource(
resource_doc = await ResourceBaseDocument.get(resource_id, with_children=True)
if not resource_doc:
raise errors.E_404_RESOURCE_NOT_FOUND
if resource_doc.public:
return await preprocess_resource_read(resource_doc, user)
if not resource_doc.proposed:
raise errors.E_400_RESOURCE_PUBLISH_UNPROPOSED
if resource_doc.original_id:
Expand Down
3 changes: 1 addition & 2 deletions Tekst-API/tekst/routers/texts.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
Body,
Depends,
File,
HTTPException,
Path,
UploadFile,
status,
)
from fastapi.responses import FileResponse
from starlette.background import BackgroundTask

from tekst import errors
from tekst.auth import OptionalUserDep, SuperuserDep
from tekst.dependencies import get_temp_dir
from tekst.logging import log
Expand All @@ -33,7 +33,6 @@
TextUpdate,
)
from tekst.settings import get_settings
from tekst import errors


router = APIRouter(
Expand Down
10 changes: 3 additions & 7 deletions Tekst-API/tests/test_api_locations.py
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ async def test_update_location(
insert_sample_data,
status_fail_msg,
login,
wrong_id,
):
text_id = (await insert_sample_data("texts", "locations"))["texts"][0]

Expand Down Expand Up @@ -297,13 +298,8 @@ async def test_update_location(

# update invalid location
location_update = {"label": "Brand new label"}
resp = await test_client.patch(
"/locations/637b9ad396d541a505e5439b", json=location_update
)
assert resp.status_code == 400, status_fail_msg(
400,
resp,
)
resp = await test_client.patch(f"/locations/{wrong_id}", json=location_update)
assert resp.status_code == 404, status_fail_msg(404, resp)


@pytest.mark.anyio
Expand Down
5 changes: 3 additions & 2 deletions Tekst-API/tests/test_api_texts.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ async def test_update_text(
insert_sample_data,
status_fail_msg,
login,
wrong_id,
):
await insert_sample_data("texts")

Expand Down Expand Up @@ -120,10 +121,10 @@ async def test_update_text(
# update invalid text
text_update = {"title": "Yet another text"}
resp = await test_client.patch(
"/texts/637b9ad396d541a505e5439b",
f"/texts/{wrong_id}",
json=text_update,
)
assert resp.status_code == 400, status_fail_msg(400, resp)
assert resp.status_code == 404, status_fail_msg(404, resp)


@pytest.mark.anyio
Expand Down
Loading

0 comments on commit 371d1ea

Please sign in to comment.