Skip to content
This repository was archived by the owner on Jun 5, 2025. It is now read-only.

Commit a438746

Browse files
committed
Use exceptions for handling workspace add error
This stops using the boolean and instead will raise exceptions if there's an issue adding a workspace. This will help us differentiate if the operation failed due to a name already being taken, or the name having invalid characters. Signed-off-by: Juan Antonio Osorio <[email protected]>
1 parent b68186c commit a438746

File tree

4 files changed

+37
-25
lines changed

4 files changed

+37
-25
lines changed

src/codegate/api/v1.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from fastapi.routing import APIRoute
44

55
from codegate.api import v1_models
6+
from codegate.db.connection import AlreadyExistsError
67
from codegate.workspaces.crud import WorkspaceCrud
78

89
v1 = APIRouter()
@@ -52,13 +53,13 @@ async def activate_workspace(request: v1_models.ActivateWorkspaceRequest, status
5253
async def create_workspace(request: v1_models.CreateWorkspaceRequest):
5354
"""Create a new workspace."""
5455
# Input validation is done in the model
55-
created = await wscrud.add_workspace(request.name)
56+
try:
57+
created = await wscrud.add_workspace(request.name)
58+
except AlreadyExistsError:
59+
raise HTTPException(status_code=409, detail="Workspace already exists")
5660

57-
# TODO: refactor to use a more specific exception
58-
if not created:
59-
raise HTTPException(status_code=400, detail="Failed to create workspace")
60-
61-
return v1_models.Workspace(name=request.name)
61+
if created:
62+
return v1_models.Workspace(name=created.name)
6263

6364

6465
@v1.delete(

src/codegate/db/connection.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
import structlog
88
from alembic import command as alembic_command
99
from alembic.config import Config as AlembicConfig
10-
from pydantic import BaseModel, ValidationError
10+
from pydantic import BaseModel
1111
from sqlalchemy import CursorResult, TextClause, text
1212
from sqlalchemy.exc import OperationalError
1313
from sqlalchemy.ext.asyncio import create_async_engine
14+
from sqlite3 import IntegrityError
1415

1516
from codegate.db.fim_cache import FimCache
1617
from codegate.db.models import (
@@ -30,6 +31,8 @@
3031
alert_queue = asyncio.Queue()
3132
fim_cache = FimCache()
3233

34+
class AlreadyExistsError(Exception):
35+
pass
3336

3437
class DbCodeGate:
3538
_instance = None
@@ -243,11 +246,14 @@ async def record_context(self, context: Optional[PipelineContext]) -> None:
243246
logger.error(f"Failed to record context: {context}.", error=str(e))
244247

245248
async def add_workspace(self, workspace_name: str) -> Optional[Workspace]:
246-
try:
247-
workspace = Workspace(id=str(uuid.uuid4()), name=workspace_name)
248-
except ValidationError as e:
249-
logger.error(f"Failed to create workspace with name: {workspace_name}: {str(e)}")
250-
return None
249+
"""Add a new workspace to the DB.
250+
251+
This handles validation and insertion of a new workspace.
252+
253+
It may raise a ValidationError if the workspace name is invalid.
254+
or a AlreadyExistsError if the workspace already exists.
255+
"""
256+
workspace = Workspace(id=str(uuid.uuid4()), name=workspace_name)
251257

252258
sql = text(
253259
"""
@@ -256,12 +262,12 @@ async def add_workspace(self, workspace_name: str) -> Optional[Workspace]:
256262
RETURNING *
257263
"""
258264
)
265+
259266
try:
260267
added_workspace = await self._execute_update_pydantic_model(workspace, sql)
261-
except Exception as e:
268+
except IntegrityError as e:
262269
logger.error(f"Failed to add workspace: {workspace_name}.", error=str(e))
263-
return None
264-
270+
raise AlreadyExistsError(f"Workspace {workspace_name} already exists.")
265271
return added_workspace
266272

267273
async def update_session(self, session: Session) -> Optional[Session]:

src/codegate/pipeline/cli/commands.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from abc import ABC, abstractmethod
2+
from pydantic import ValidationError
23
from typing import List
34

45
from codegate import __version__
6+
from codegate.db.connection import AlreadyExistsError
57
from codegate.workspaces.crud import WorkspaceCrud
68

79

@@ -69,14 +71,14 @@ async def _add_workspace(self, args: List[str]) -> str:
6971
if not new_workspace_name:
7072
return "Please provide a name. Use `codegate workspace add your_workspace_name`"
7173

72-
workspace_created = await self.workspace_crud.add_workspace(new_workspace_name)
73-
if not workspace_created:
74-
return (
75-
"Something went wrong. Workspace could not be added.\n"
76-
"1. Check if the name is alphanumeric and only contains dashes, and underscores.\n"
77-
"2. Check if the workspace already exists."
78-
)
79-
return f"Workspace **{new_workspace_name}** has been added"
74+
try:
75+
workspace_created = await self.workspace_crud.add_workspace(new_workspace_name)
76+
except ValidationError as e:
77+
return f"Invalid workspace name: {e}"
78+
except AlreadyExistsError as e:
79+
return f"Workspace **{new_workspace_name}** already exists"
80+
81+
return f"Workspace **{workspace_created.name}** has been added"
8082

8183
async def _activate_workspace(self, args: List[str]) -> str:
8284
"""

src/codegate/workspaces/crud.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
from codegate.db.models import Session, Workspace, WorkspaceActive, ActiveWorkspace
66

77

8+
class WorkspaceCrudError(Exception):
9+
pass
10+
811
class WorkspaceCrud:
912

1013
def __init__(self):
1114
self._db_reader = DbReader()
1215

13-
async def add_workspace(self, new_workspace_name: str) -> bool:
16+
async def add_workspace(self, new_workspace_name: str) -> Workspace:
1417
"""
1518
Add a workspace
1619
@@ -19,7 +22,7 @@ async def add_workspace(self, new_workspace_name: str) -> bool:
1922
"""
2023
db_recorder = DbRecorder()
2124
workspace_created = await db_recorder.add_workspace(new_workspace_name)
22-
return bool(workspace_created)
25+
return workspace_created
2326

2427
async def get_workspaces(self)-> List[WorkspaceActive]:
2528
"""

0 commit comments

Comments
 (0)