@@ -147,20 +147,28 @@ def _validate_project_dir(resolved_path: Path) -> None:
147147 """
148148 # Blocklist for dangerous locations
149149 dangerous_roots = [
150- Path ("/" ).resolve (), # Root
151- Path ("/etc" ).resolve (), # System config
152- Path ("/var" ).resolve (), # System variables
153- Path .home ().resolve (), # User home (allow subpaths, block direct home)
150+ (Path ("/etc" ).resolve (), "tree" ), # System config - block entire tree
151+ (Path ("/var" ).resolve (), "tree" ), # System variables - block entire tree
152+ (Path .home ().resolve (), "exact" ), # User home - block exact match only, allow subpaths
154153 ]
155154
156155 # Check if path is in dangerous locations
157- for dangerous in dangerous_roots :
156+ for dangerous , block_type in dangerous_roots :
158157 try :
159- if dangerous in resolved_path .parents or dangerous == resolved_path :
160- raise HTTPException (
161- status_code = 404 ,
162- detail = f"Project not found: { resolved_path } "
163- )
158+ if block_type == "tree" :
159+ # Block entire directory tree (e.g., /etc, /var)
160+ if resolved_path .is_relative_to (dangerous ):
161+ raise HTTPException (
162+ status_code = 404 ,
163+ detail = f"Project not found: { resolved_path } "
164+ )
165+ elif block_type == "exact" :
166+ # Block exact match only (e.g., home directory itself)
167+ if resolved_path == dangerous :
168+ raise HTTPException (
169+ status_code = 404 ,
170+ detail = f"Project not found: { resolved_path } "
171+ )
164172 except (ValueError , OSError ):
165173 pass
166174
@@ -202,7 +210,7 @@ async def run_code_review(request: RunReviewRequest):
202210 # Validate file paths to prevent directory traversal
203211 if request .files :
204212 for file_path in request .files :
205- if ".." in file_path or file_path .startswith ("/" ) or file_path .startswith ("\\ " ):
213+ if ".." in file_path or file_path .startswith ("/" ) or file_path .startswith ("\\ " ) or Path ( file_path ). is_absolute () :
206214 raise HTTPException (status_code = 400 , detail = f"Invalid file path: { file_path } " )
207215
208216 # Configure checks
@@ -241,8 +249,8 @@ async def run_code_review(request: RunReviewRequest):
241249 )
242250
243251 except Exception as e :
244- logger .error (f"Review failed for { project_dir } : { e } " )
245- raise HTTPException (status_code = 500 , detail = str ( e ) )
252+ logger .error (f"Review failed for { project_dir } : { e } " , exc_info = True )
253+ raise HTTPException (status_code = 500 , detail = "Code review failed. Check server logs for details." )
246254
247255
248256@router .get ("/reports/{project_name}" , response_model = ReportListResponse )
@@ -275,7 +283,7 @@ async def list_reports(project_name: str):
275283 )
276284 )
277285 except Exception as e :
278- logger .warning (f"Error reading report { report_file } : { e } " )
286+ logger .warning (f"Error reading report { report_file } : { e } " , exc_info = True )
279287 continue
280288
281289 return ReportListResponse (reports = reports , count = len (reports ))
@@ -300,7 +308,8 @@ async def get_report(project_name: str, filename: str):
300308 with open (report_path ) as f :
301309 return json .load (f )
302310 except Exception as e :
303- raise HTTPException (status_code = 500 , detail = f"Error reading report: { e } " )
311+ logger .error (f"Error reading report { report_path } : { e } " , exc_info = True )
312+ raise HTTPException (status_code = 500 , detail = "Error reading report. Check server logs for details." )
304313
305314
306315@router .post ("/create-features" , response_model = CreateFeaturesResponse )
@@ -361,8 +370,10 @@ async def create_features_from_issues(request: CreateFeaturesRequest):
361370 )
362371
363372 except Exception as e :
364- logger .error (f"Failed to create features: { e } " )
365- raise HTTPException (status_code = 500 , detail = str (e ))
373+ if session :
374+ session .rollback ()
375+ logger .error (f"Failed to create features: { e } " , exc_info = True )
376+ raise HTTPException (status_code = 500 , detail = "Failed to create features. Check server logs for details." )
366377 finally :
367378 if session :
368379 session .close ()
@@ -387,4 +398,5 @@ async def delete_report(project_name: str, filename: str):
387398 report_path .unlink ()
388399 return {"deleted" : True , "filename" : filename }
389400 except Exception as e :
390- raise HTTPException (status_code = 500 , detail = f"Error deleting report: { e } " )
401+ logger .error (f"Error deleting report { report_path } : { e } " , exc_info = True )
402+ raise HTTPException (status_code = 500 , detail = "Error deleting report. Check server logs for details." )
0 commit comments