From d41d740768a27ae847ba5d08971b0c2897b04f0d Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 18 Dec 2024 12:04:25 -0300 Subject: [PATCH] fix: make errors in build_flow function use the standardized ErrorMessage schema (#5199) * fix: enhance error handling in build_flow function by utilizing ErrorMessage schema - Introduced ErrorMessage schema to standardize error reporting in the build_flow function. - Updated error handling to include flow_id, session_id, and trace_name for better context in error messages. - Improved clarity and maintainability of error handling logic across multiple exception cases. * Remove session_id from ErrorMessage in chat endpoint * fix: enhance error handling in build_flow function by checking for custom component existence Updated the error handling logic in the build_flow function to safely access the trace_name of the custom component. This change ensures that if the custom component is not present, the trace_name will be set to None, improving the robustness of error reporting. * fix: update ErrorMessage schema to allow optional session_id and source - Modified the ErrorMessage class to accept optional parameters for session_id and source, enhancing flexibility in error reporting. - Updated the initialization logic to handle None values for sender and component attributes, ensuring robustness in cases where source may not be provided. * fix: improve error handling in build_flow function by using getattr for trace_name Updated the error handling logic in the build_flow function to utilize getattr for safely accessing the trace_name attribute of the custom component. This change ensures that if the custom component is not present, trace_name will default to None, enhancing the robustness of error reporting. --- src/backend/base/langflow/api/v1/chat.py | 29 ++++++++++++++------- src/backend/base/langflow/schema/message.py | 12 ++++----- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/backend/base/langflow/api/v1/chat.py b/src/backend/base/langflow/api/v1/chat.py index 587161c31..6aaf2988b 100644 --- a/src/backend/base/langflow/api/v1/chat.py +++ b/src/backend/base/langflow/api/v1/chat.py @@ -39,6 +39,7 @@ from langflow.events.event_manager import EventManager, create_default_event_man from langflow.exceptions.component import ComponentBuildError from langflow.graph.graph.base import Graph from langflow.graph.utils import log_vertex_build +from langflow.schema.message import ErrorMessage from langflow.schema.schema import OutputValue from langflow.services.cache.utils import CacheMiss from langflow.services.chat.service import ChatService @@ -376,10 +377,11 @@ async def build_flow( vertices_task.cancel() return except Exception as e: - if isinstance(e, HTTPException): - event_manager.on_error(data={"error": str(e.detail), "statusCode": e.status_code}) - raise - event_manager.on_error(data={"error": str(e)}) + error_message = ErrorMessage( + flow_id=flow_id, + exception=e, + ) + event_manager.on_error(data=error_message.data) raise ids, vertices_to_run, graph = vertices_task.result() @@ -387,10 +389,11 @@ async def build_flow( try: ids, vertices_to_run, graph = await build_graph_and_get_order() except Exception as e: - if isinstance(e, HTTPException): - event_manager.on_error(data={"error": str(e.detail), "statusCode": e.status_code}) - raise - event_manager.on_error(data={"error": str(e)}) + error_message = ErrorMessage( + flow_id=flow_id, + exception=e, + ) + event_manager.on_error(data=error_message.data) raise event_manager.on_vertices_sorted(data={"ids": ids, "to_run": vertices_to_run}) await client_consumed_queue.get() @@ -408,7 +411,15 @@ async def build_flow( return except Exception as e: logger.error(f"Error building vertices: {e}") - event_manager.on_error(data={"error": str(e)}) + custom_component = graph.get_vertex(vertex_id).custom_component + trace_name = getattr(custom_component, "trace_name", None) + error_message = ErrorMessage( + flow_id=flow_id, + exception=e, + session_id=graph.session_id, + trace_name=trace_name, + ) + event_manager.on_error(data=error_message.data) raise event_manager.on_end(data={}) await event_manager.queue.put((None, None, time.time)) diff --git a/src/backend/base/langflow/schema/message.py b/src/backend/base/langflow/schema/message.py index 16f0fa847..11d1a1211 100644 --- a/src/backend/base/langflow/schema/message.py +++ b/src/backend/base/langflow/schema/message.py @@ -371,10 +371,10 @@ class ErrorMessage(Message): def __init__( self, exception: BaseException, - session_id: str, - source: Source, + session_id: str | None = None, + source: Source | None = None, trace_name: str | None = None, - flow_id: str | None = None, + flow_id: UUID | str | None = None, ) -> None: # This is done to avoid circular imports if exception.__class__.__name__ == "ExceptionWithMessageError" and exception.__cause__ is not None: @@ -400,8 +400,8 @@ class ErrorMessage(Message): super().__init__( session_id=session_id, - sender=source.display_name, - sender_name=source.display_name, + sender=source.display_name if source else None, + sender_name=source.display_name if source else None, text=reason, properties=Properties( text_color="red", @@ -420,7 +420,7 @@ class ErrorMessage(Message): contents=[ ErrorContent( type="error", - component=source.display_name, + component=source.display_name if source else None, field=str(exception.field) if hasattr(exception, "field") else None, reason=reason, solution=str(exception.solution) if hasattr(exception, "solution") else None,