Skip to content

Commit

Permalink
Merge pull request #5139 from opsmill/lgu-fix-error-on-missing-file
Browse files Browse the repository at this point in the history
Fix error message returned while querying for a missing repository file
  • Loading branch information
LucasG0 authored Dec 9, 2024
2 parents 49e9dfe + 7113231 commit e25a602
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 8 deletions.
6 changes: 5 additions & 1 deletion backend/infrahub/api/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from infrahub.core.constants import InfrahubKind
from infrahub.core.manager import NodeManager
from infrahub.database import InfrahubDatabase # noqa: TCH001
from infrahub.exceptions import CommitNotFoundError
from infrahub.exceptions import CommitNotFoundError, PropagatedFromWorkerError
from infrahub.message_bus.messages import GitFileGet, GitFileGetResponse

if TYPE_CHECKING:
Expand Down Expand Up @@ -60,4 +60,8 @@ async def get_file(
)

response = await service.message_bus.rpc(message=message, response_class=GitFileGetResponse)
if response.data.http_code is not None:
assert response.data.error_message is not None
raise PropagatedFromWorkerError(message=response.data.error_message, http_code=response.data.http_code)

return PlainTextResponse(content=response.data.content)
11 changes: 11 additions & 0 deletions backend/infrahub/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ def api_response(self) -> dict[str, Any]:
}


class PropagatedFromWorkerError(Error):
"""
Used to re-raise server side an error that happened worker side.
Note we might want to improve this so we raise the exact same error that happened worker side.
"""

def __init__(self, http_code: int, message: str) -> None:
self.HTTP_CODE = http_code
self.message = message


class RPCError(Error):
HTTP_CODE: int = 502

Expand Down
4 changes: 3 additions & 1 deletion backend/infrahub/message_bus/messages/git_file_get.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ class GitFileGet(InfrahubMessage):


class GitFileGetResponseData(InfrahubResponseData):
content: str = Field(..., description="The returned content")
content: str | None = None # is empty if error_message / http_code are not empty
error_message: str | None = None
http_code: int | None = None


class GitFileGetResponse(InfrahubResponse):
Expand Down
21 changes: 15 additions & 6 deletions backend/infrahub/message_bus/operations/git/file.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
from prefect import flow

from infrahub.exceptions import FileOutOfRepositoryError, RepositoryFileNotFoundError
from infrahub.git.repository import get_initialized_repo
from infrahub.log import get_logger
from infrahub.message_bus import messages
from infrahub.message_bus.messages.git_file_get import GitFileGetResponse, GitFileGetResponseData
from infrahub.message_bus.messages.git_file_get import (
GitFileGetResponse,
GitFileGetResponseData,
)
from infrahub.services import InfrahubServices

log = get_logger()
Expand All @@ -20,8 +24,13 @@ async def get(message: messages.GitFileGet, service: InfrahubServices) -> None:
repository_kind=message.repository_kind,
)

content = await repo.get_file(commit=message.commit, location=message.file)

if message.reply_requested:
response = GitFileGetResponse(data=GitFileGetResponseData(content=content))
await service.reply(message=response, initiator=message)
try:
content = await repo.get_file(commit=message.commit, location=message.file)
except (FileOutOfRepositoryError, RepositoryFileNotFoundError) as e:
if message.reply_requested:
response = GitFileGetResponse(data=GitFileGetResponseData(error_message=e.message, http_code=e.HTTP_CODE))
await service.reply(message=response, initiator=message)
else:
if message.reply_requested:
response = GitFileGetResponse(data=GitFileGetResponseData(content=content))
await service.reply(message=response, initiator=message)
40 changes: 40 additions & 0 deletions backend/tests/integration/git/test_git_repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import yaml
from infrahub_sdk import Config, InfrahubClient
from infrahub_sdk.exceptions import NodeNotFoundError
from starlette.testclient import TestClient

from infrahub import config
from infrahub.core import registry
Expand All @@ -20,6 +21,7 @@
from infrahub.utils import get_models_dir
from tests.adapters.log import FakeTaskReportLogger
from tests.helpers.file_repo import FileRepo
from tests.helpers.test_app import TestInfrahubApp
from tests.helpers.test_client import InfrahubTestClient

# pylint: disable=unused-argument
Expand Down Expand Up @@ -293,3 +295,41 @@ async def test_import_all_yaml_files(
# FIXME not implemented yet
with pytest.raises(NodeNotFoundError):
await client.get(kind=InfrahubKind.TRANSFORMJINJA2, id=obj.id)


class TestGetMissingFile(TestInfrahubApp):
async def test_get_missing_file(self, db: InfrahubDatabase, client: InfrahubClient, git_repo_car_dealership):
# Ideally above tests would rely on `TestInfrahubApp.repo` instead of TestInfrahubClient
# and we would reuse `TestInfrahubClient.repo` fixture here.
obj = await Node.init(schema=InfrahubKind.REPOSITORY, db=db)
await obj.new(
db=db,
name=git_repo_car_dealership.name,
description="test repository",
location="git@github.com:mock/test.git",
)
await obj.save(db=db)

# Initialize the repository on the file system
repo = await InfrahubRepository.new(
id=obj.id,
name=git_repo_car_dealership.name,
location=git_repo_car_dealership.path,
task_report=FakeTaskReportLogger(),
client=client,
)

commit = repo.get_commit_value(branch_name="main")
rest_client = TestClient(app)
missing_file_name = "i_do_not_exist.txt"
with rest_client:
response = rest_client.get(
url=f"/api/file/{repo.id}/{missing_file_name}?commit={commit}",
headers={"Authorization": "Token XXXX"},
)
errors = response.json()["errors"]
assert len(errors) == 1
assert (
errors[0]["message"] == f"Unable to find the file at 'car-dealership::{commit}::{missing_file_name}'."
)
assert errors[0]["extensions"]["code"] == 404

0 comments on commit e25a602

Please sign in to comment.