mirror of
https://github.com/Pythagora-io/gpt-pilot.git
synced 2026-01-08 12:53:50 -05:00
Implemented fatal errors
This commit is contained in:
@@ -82,37 +82,36 @@ async def run_project(sm: StateManager, ui: UIBase, args) -> bool:
|
|||||||
telemetry.set("end_result", "interrupt")
|
telemetry.set("end_result", "interrupt")
|
||||||
await sm.rollback()
|
await sm.rollback()
|
||||||
except APIError as err:
|
except APIError as err:
|
||||||
log.warning(f"LLM API error occurred: {err.message}")
|
log.warning(f"an LLM API error occurred: {err.message}")
|
||||||
capture_exception(err)
|
await send_error(ui, "error while calling the LLM API", err)
|
||||||
await ui.send_message(
|
|
||||||
f"Stopping Pythagora due to an error while calling the LLM API: {err.message}",
|
|
||||||
source=pythagora_source,
|
|
||||||
)
|
|
||||||
telemetry.set("end_result", "failure:api-error")
|
telemetry.set("end_result", "failure:api-error")
|
||||||
await sm.rollback()
|
await sm.rollback()
|
||||||
except CustomAssertionError as err:
|
except CustomAssertionError as err:
|
||||||
log.warning(f"Anthropic assertion error occurred: {str(err)}")
|
log.warning(f"an Anthropic assertion error occurred: {str(err)}")
|
||||||
capture_exception(err)
|
await send_error(ui, "error inside Anthropic SDK", err)
|
||||||
await ui.send_message(
|
|
||||||
f"Stopping Pythagora due to an error inside Anthropic SDK. {str(err)}",
|
|
||||||
source=pythagora_source,
|
|
||||||
)
|
|
||||||
telemetry.set("end_result", "failure:assertion-error")
|
telemetry.set("end_result", "failure:assertion-error")
|
||||||
await sm.rollback()
|
await sm.rollback()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
log.error(f"Uncaught exception: {err}", exc_info=True)
|
log.error(f"Uncaught exception: {err}", exc_info=True)
|
||||||
capture_exception(err)
|
await send_error(ui, "an error", err)
|
||||||
|
|
||||||
stack_trace = telemetry.record_crash(err)
|
telemetry.record_crash(err)
|
||||||
await sm.rollback()
|
await sm.rollback()
|
||||||
await ui.send_message(
|
|
||||||
f"Stopping Pythagora due to error:\n\n{stack_trace}",
|
|
||||||
source=pythagora_source,
|
|
||||||
)
|
|
||||||
|
|
||||||
return success
|
return success
|
||||||
|
|
||||||
|
|
||||||
|
async def send_error(ui: UIBase, error_source: str, err: Exception):
|
||||||
|
await ui.send_fatal_error(
|
||||||
|
f"Stopping Pythagora due to {error_source}:\n\n{err}",
|
||||||
|
source=pythagora_source,
|
||||||
|
extra_info={
|
||||||
|
"fatal_error": True,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
capture_exception(err)
|
||||||
|
|
||||||
|
|
||||||
async def start_new_project(sm: StateManager, ui: UIBase, args: Namespace = None) -> bool:
|
async def start_new_project(sm: StateManager, ui: UIBase, args: Namespace = None) -> bool:
|
||||||
"""
|
"""
|
||||||
Start a new project.
|
Start a new project.
|
||||||
@@ -368,7 +367,7 @@ async def async_main(
|
|||||||
success = await run_pythagora_session(sm, ui, args)
|
success = await run_pythagora_session(sm, ui, args)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
log.error(f"Uncaught exception in main session: {err}", exc_info=True)
|
log.error(f"Uncaught exception in main session: {err}", exc_info=True)
|
||||||
capture_exception(err)
|
await send_error(ui, "an error", err)
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
await cleanup(ui)
|
await cleanup(ui)
|
||||||
|
|||||||
@@ -516,6 +516,15 @@ class UIBase:
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
async def send_fatal_error(
|
||||||
|
self,
|
||||||
|
message: str,
|
||||||
|
extra_info: Optional[dict] = None,
|
||||||
|
source: Optional[UISource] = None,
|
||||||
|
project_state_id: Optional[str] = None,
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
async def send_front_logs_headers(
|
async def send_front_logs_headers(
|
||||||
self,
|
self,
|
||||||
project_state_id: str,
|
project_state_id: str,
|
||||||
|
|||||||
@@ -240,6 +240,15 @@ class PlainConsoleUI(UIBase):
|
|||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
async def send_fatal_error(
|
||||||
|
self,
|
||||||
|
message: str,
|
||||||
|
extra_info: Optional[dict] = None,
|
||||||
|
source: Optional[UISource] = None,
|
||||||
|
project_state_id: Optional[str] = None,
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
async def send_front_logs_headers(
|
async def send_front_logs_headers(
|
||||||
self,
|
self,
|
||||||
project_state_id: str,
|
project_state_id: str,
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ class MessageType(str, Enum):
|
|||||||
LOAD_FRONT_LOGS = "loadFrontLogs"
|
LOAD_FRONT_LOGS = "loadFrontLogs"
|
||||||
FRONT_LOGS_HEADERS = "frontLogsHeaders"
|
FRONT_LOGS_HEADERS = "frontLogsHeaders"
|
||||||
CLEAR_MAIN_LOGS = "clearMainLogs"
|
CLEAR_MAIN_LOGS = "clearMainLogs"
|
||||||
|
FATAL_ERROR = "fatalError"
|
||||||
|
|
||||||
|
|
||||||
class Message(BaseModel):
|
class Message(BaseModel):
|
||||||
@@ -621,6 +622,21 @@ class IPCClientUI(UIBase):
|
|||||||
|
|
||||||
await self._send(MessageType.BACK_LOGS, content={"items": items})
|
await self._send(MessageType.BACK_LOGS, content={"items": items})
|
||||||
|
|
||||||
|
async def send_fatal_error(
|
||||||
|
self,
|
||||||
|
message: str,
|
||||||
|
extra_info: Optional[dict] = None,
|
||||||
|
source: Optional[UISource] = None,
|
||||||
|
project_state_id: Optional[str] = None,
|
||||||
|
):
|
||||||
|
await self._send(
|
||||||
|
MessageType.FATAL_ERROR,
|
||||||
|
content=message,
|
||||||
|
category=source.type_name if source else None,
|
||||||
|
project_state_id=project_state_id,
|
||||||
|
extra_info=extra_info,
|
||||||
|
)
|
||||||
|
|
||||||
async def send_front_logs_headers(
|
async def send_front_logs_headers(
|
||||||
self,
|
self,
|
||||||
project_state_id: str,
|
project_state_id: str,
|
||||||
|
|||||||
@@ -228,6 +228,15 @@ class VirtualUI(UIBase):
|
|||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
async def send_fatal_error(
|
||||||
|
self,
|
||||||
|
message: str,
|
||||||
|
extra_info: Optional[dict] = None,
|
||||||
|
source: Optional[UISource] = None,
|
||||||
|
project_state_id: Optional[str] = None,
|
||||||
|
):
|
||||||
|
pass
|
||||||
|
|
||||||
async def send_front_logs_headers(
|
async def send_front_logs_headers(
|
||||||
self,
|
self,
|
||||||
project_state_id: str,
|
project_state_id: str,
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ async def test_main_handles_crash(mock_Orchestrator, tmp_path):
|
|||||||
mock_response = MagicMock(text="test", cancelled=False)
|
mock_response = MagicMock(text="test", cancelled=False)
|
||||||
mock_response.button = "test_project_type" # Set a string value for project_type
|
mock_response.button = "test_project_type" # Set a string value for project_type
|
||||||
ui.ask_question = AsyncMock(return_value=mock_response)
|
ui.ask_question = AsyncMock(return_value=mock_response)
|
||||||
ui.send_message = AsyncMock()
|
ui.send_fatal_error = AsyncMock()
|
||||||
|
|
||||||
mock_orca = mock_Orchestrator.return_value
|
mock_orca = mock_Orchestrator.return_value
|
||||||
mock_orca.run = AsyncMock(side_effect=RuntimeError("test error"))
|
mock_orca.run = AsyncMock(side_effect=RuntimeError("test error"))
|
||||||
@@ -350,5 +350,5 @@ async def test_main_handles_crash(mock_Orchestrator, tmp_path):
|
|||||||
success = await async_main(ui, db, args)
|
success = await async_main(ui, db, args)
|
||||||
|
|
||||||
assert success is False
|
assert success is False
|
||||||
ui.send_message.assert_called_once()
|
ui.send_fatal_error.assert_called_once()
|
||||||
assert "test error" in ui.send_message.call_args[0][0]
|
assert "test error" in ui.send_fatal_error.call_args[0][0]
|
||||||
|
|||||||
Reference in New Issue
Block a user