Skip to content

Commit

Permalink
refactor(backend): better error handling in backend (#277)
Browse files Browse the repository at this point in the history
Add specific messages if Github settings were not added and change some status codes in backend

### What
Some errors raised by backend have a 500 status code intead of having 4XX error.
For example, if a developer forgets to add a Personal Access Token and wants to import a project to edit, the server throws a 500 error instead of 400 error.

### Screenshot
![image](https://github.com/openfoodfacts/taxonomy-editor/assets/106757110/e0c24f5a-9de7-47b1-a31b-20741729df8b)

### Fixes bug(s)

### Part of 
- backend/editor


---------

Co-authored-by: alice.juan <[email protected]>
  • Loading branch information
Piv94165 and alice.juan authored Nov 10, 2023
1 parent 089df89 commit af9e1f3
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 21 deletions.
23 changes: 17 additions & 6 deletions backend/editor/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
status,
)
from fastapi.encoders import jsonable_encoder
from fastapi.exception_handlers import http_exception_handler
from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import FileResponse, JSONResponse
Expand Down Expand Up @@ -110,8 +111,8 @@ def file_cleanup(filepath):
"""
try:
os.remove(filepath)
except Exception as e:
raise HTTPException(status_code=500, detail="Taxonomy file not found for deletion") from e
except FileNotFoundError:
log.warn(f"Taxonomy file {filepath} not found for deletion")


class StatusFilter(str, Enum):
Expand Down Expand Up @@ -139,6 +140,16 @@ async def validation_exception_handler(request: Request, exc: RequestValidationE
)


@app.exception_handler(HTTPException)
async def log_http_exception(request: Request, exc: HTTPException):
"""
Custom exception handler to log FastAPI exceptions.
"""
# Log the detail message
log.info(f" ERROR: {exc.detail}")
return await http_exception_handler(request, exc)


# Get methods


Expand Down Expand Up @@ -351,10 +362,10 @@ async def export_to_github(
return url

except GithubBranchExistsError:
raise HTTPException(status_code=500, detail="The Github branch already exists!")
raise HTTPException(status_code=409, detail="The Github branch already exists!")

except GithubUploadError:
raise HTTPException(status_code=500, detail="Github upload error!")
raise HTTPException(status_code=400, detail="Github upload error!")


# Post methods
Expand All @@ -370,7 +381,7 @@ async def import_from_github(request: Request, branch: str, taxonomy_name: str):

taxonomy = TaxonomyGraph(branch, taxonomy_name)
if not taxonomy.is_valid_branch_name():
raise HTTPException(status_code=400, detail="branch_name: Enter a valid branch name!")
raise HTTPException(status_code=422, detail="branch_name: Enter a valid branch name!")
if await taxonomy.does_project_exist():
raise HTTPException(status_code=409, detail="Project already exists!")
if not await taxonomy.is_branch_unique():
Expand All @@ -390,7 +401,7 @@ async def upload_taxonomy(
# use the file name as the taxonomy name
taxonomy = TaxonomyGraph(branch, taxonomy_name)
if not taxonomy.is_valid_branch_name():
raise HTTPException(status_code=400, detail="branch_name: Enter a valid branch name!")
raise HTTPException(status_code=422, detail="branch_name: Enter a valid branch name!")
if await taxonomy.does_project_exist():
raise HTTPException(status_code=409, detail="Project already exists!")
if not await taxonomy.is_branch_unique():
Expand Down
51 changes: 36 additions & 15 deletions backend/editor/github_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"""
from textwrap import dedent

from github import Github
from fastapi import HTTPException
from github import Github, GithubException

from . import settings

Expand All @@ -21,8 +22,19 @@ def init_driver_and_repo(self):
"""
Initalize connection to Github with an access token
"""
github_driver = Github(settings.access_token)
repo = github_driver.get_repo(settings.repo_uri)
access_token = settings.access_token
if not access_token:
raise HTTPException(
status_code=400,
detail="Access token is not set. Please add your access token in .env",
)
repo_uri = settings.repo_uri
if not repo_uri:
raise HTTPException(
status_code=400, detail="repo_uri is not set. Please add your access token in .env"
)
github_driver = Github(access_token)
repo = github_driver.get_repo(repo_uri)
return repo

def list_all_branches(self):
Expand All @@ -47,19 +59,28 @@ def update_file(self, filename):
# Find taxonomy text file to be updated
github_filepath = f"taxonomies/{self.taxonomy_name}.txt"
commit_message = f"Update {self.taxonomy_name}.txt"
try:
current_file = self.repo.get_contents(github_filepath)
with open(filename, "r") as f:
new_file_contents = f.read()

current_file = self.repo.get_contents(github_filepath)
with open(filename, "r") as f:
new_file_contents = f.read()

# Update the file
self.repo.update_file(
github_filepath,
commit_message,
new_file_contents,
current_file.sha,
branch=self.branch_name,
)
# Update the file
self.repo.update_file(
github_filepath,
commit_message,
new_file_contents,
current_file.sha,
branch=self.branch_name,
)
except GithubException as e:
# Handle GitHub API-related exceptions
raise Exception(f"GitHub API error: {e}") from e
except FileNotFoundError as e:
# Handle file not found error (e.g., when 'filename' does not exist)
raise Exception(f"File not found: {filename}") from e
except Exception as e:
# Handle any other unexpected exceptions
raise Exception(f"An error occurred: {e}") from e

def create_pr(self, description):
"""
Expand Down

0 comments on commit af9e1f3

Please sign in to comment.