diff --git a/src/backend/base/langflow/api/v1/chat.py b/src/backend/base/langflow/api/v1/chat.py index 703ea1240..f57aaa0b8 100644 --- a/src/backend/base/langflow/api/v1/chat.py +++ b/src/backend/base/langflow/api/v1/chat.py @@ -1,4 +1,5 @@ import time +import traceback import uuid from functools import partial from typing import TYPE_CHECKING, Annotated, Optional @@ -189,11 +190,13 @@ async def build_vertex( result_data_response = ResultDataResponse.model_validate(result_dict, from_attributes=True) except Exception as exc: + tb = traceback.format_exc() logger.exception(f"Error building Component: {exc}") params = format_exception_message(exc) + message = {"errorMessage": params, "stackTrace": tb} valid = False output_label = vertex.outputs[0]["name"] if vertex.outputs else "output" - logs = {output_label: Log(message=params, type="error")} + logs = {output_label: Log(message=message, type="error")} result_data_response = ResultDataResponse(results={}, logs=logs) artifacts = {} # If there's an error building the vertex @@ -243,7 +246,7 @@ async def build_vertex( ) return build_response except Exception as exc: - logger.error(f"Error building Component: {exc}") + logger.error(f"Error building Component:\n\n{exc}") logger.exception(exc) message = parse_exception(exc) raise HTTPException(status_code=500, detail=message) from exc diff --git a/src/backend/base/langflow/graph/graph/base.py b/src/backend/base/langflow/graph/graph/base.py index 3778a0268..b06cfc0a6 100644 --- a/src/backend/base/langflow/graph/graph/base.py +++ b/src/backend/base/langflow/graph/graph/base.py @@ -830,7 +830,7 @@ class Graph: log_transaction(flow_id, vertex, status="success") return result_dict, params, valid, artifacts, vertex except Exception as exc: - logger.exception(f"Error building Component: {exc}") + logger.exception(f"Error building Component:\n\n{exc}") flow_id = self.flow_id log_transaction(flow_id, vertex, status="failure", error=str(exc)) raise exc diff --git a/src/backend/base/langflow/graph/vertex/base.py b/src/backend/base/langflow/graph/vertex/base.py index 89bf79e25..ed1c6ba1f 100644 --- a/src/backend/base/langflow/graph/vertex/base.py +++ b/src/backend/base/langflow/graph/vertex/base.py @@ -582,7 +582,7 @@ class Vertex: logger.exception(e) raise ValueError( f"Params {key} ({self.params[key]}) is not a list and cannot be extended with {result}" - f"Error building Component {self.display_name}: {str(e)}" + f"Error building Component {self.display_name}:\n\n{str(e)}" ) from e def _handle_func(self, key, result): @@ -622,11 +622,8 @@ class Vertex: self.logs = build_logs(self, result) self._update_built_object_and_artifacts(result) except Exception as exc: - tb = traceback.format_exc() - error_detail = f"Error: {exc}\nTraceback: {tb}" - logger.exception(error_detail) - - raise ValueError(f"Error building Component {self.display_name}: {error_detail}") from exc + logger.exception(exc) + raise ValueError(f"Error building Component {self.display_name}:\n\n{exc}") from exc def _update_built_object_and_artifacts(self, result): """ diff --git a/src/backend/base/langflow/schema/schema.py b/src/backend/base/langflow/schema/schema.py index c85bdf401..88f38f638 100644 --- a/src/backend/base/langflow/schema/schema.py +++ b/src/backend/base/langflow/schema/schema.py @@ -2,6 +2,7 @@ from enum import Enum from typing import Generator, Literal, Union from pydantic import BaseModel +from typing_extensions import TypedDict from langflow.schema import Data from langflow.schema.message import Message @@ -22,12 +23,17 @@ class LogType(str, Enum): UNKNOWN = "unknown" -class StreamURL(BaseModel): +class StreamURL(TypedDict): location: str +class ErrorLog(TypedDict): + errorMessage: str + stackTrace: str + + class Log(BaseModel): - message: Union[StreamURL, dict, list, str] + message: Union[ErrorLog, StreamURL, dict, list, str] type: str diff --git a/src/frontend/src/CustomNodes/GenericNode/components/outputModal/components/switchOutputView/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/outputModal/components/switchOutputView/index.tsx index 4a8322eee..1ab8d7334 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/outputModal/components/switchOutputView/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/outputModal/components/switchOutputView/index.tsx @@ -41,7 +41,9 @@ const SwitchOutputView: React.FC = ({
NO OUTPUT
- + diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index e3fae72bd..e83e73ee9 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -26,6 +26,7 @@ import { useShortcutsStore } from "../../../../stores/shortcuts"; import { useTypesStore } from "../../../../stores/typesStore"; import { APIClassType } from "../../../../types/api"; import { ParameterComponentType } from "../../../../types/components"; +import { isErrorLog } from "../../../../types/utils/typeCheckingUtils"; import { debouncedHandleUpdateValues, handleUpdateValues, @@ -114,11 +115,9 @@ export default function ParameterComponent({ if (!outputName) return; const logs = data?.logs[outputName]; if (Array.isArray(logs) && logs.length > 1) { - return logs.some( - (log) => log.type === "error" || log.type === "ValueError", - ); + return logs.some((log) => isErrorLog(log)); } else { - return logs?.type === "error" || logs?.type === "ValueError"; + return isErrorLog(logs); } }; @@ -129,11 +128,6 @@ export default function ParameterComponent({ !!flowPool[data.id] && logHasMessage(flowPool[data.id][flowPool[data.id].length - 1]?.data); - let hasOutputs; - if (flowPoolNode?.data?.logs && outputName) { - hasOutputs = flowPoolNode?.data?.logs[outputName] ?? null; - } - const unknownOutput = logTypeIsUnknown(flowPoolNode?.data); const errorOutput = logTypeIsError(flowPoolNode?.data); diff --git a/src/frontend/src/CustomNodes/hooks/use-validation-status-string.tsx b/src/frontend/src/CustomNodes/hooks/use-validation-status-string.tsx index eeef33bf8..bb37900d5 100644 --- a/src/frontend/src/CustomNodes/hooks/use-validation-status-string.tsx +++ b/src/frontend/src/CustomNodes/hooks/use-validation-status-string.tsx @@ -1,5 +1,6 @@ import { useEffect } from "react"; -import { LogType, VertexBuildTypeAPI } from "../../types/api"; +import { VertexBuildTypeAPI } from "../../types/api"; +import { isErrorLog } from "../../types/utils/typeCheckingUtils"; const useValidationStatusString = ( validationStatus: VertexBuildTypeAPI, @@ -8,11 +9,10 @@ const useValidationStatusString = ( useEffect(() => { if (validationStatus?.data?.logs) { // if it is not a string turn it into a string - console.log("validationStatus", validationStatus); let newValidationString = ""; Object.values(validationStatus?.data?.logs).forEach((log: any) => { - if (log.type === "error" || log.type === "ValueError") { - newValidationString += `${log.message}\n`; + if (isErrorLog(log)) { + newValidationString += `${log.message.errorMessage}\n`; } }); setValidationString(newValidationString); diff --git a/src/frontend/src/types/api/index.ts b/src/frontend/src/types/api/index.ts index 8d7d9a7e1..5c60f6cf2 100644 --- a/src/frontend/src/types/api/index.ts +++ b/src/frontend/src/types/api/index.ts @@ -181,8 +181,13 @@ export type VertexBuildTypeAPI = { artifacts: any | ChatOutputType | ChatInputType; }; +export type ErrorLogType = { + errorMessage: string; + stackTrace: string; +}; + export type LogType = { - message: any; + message: any | ErrorLogType; type: string; }; diff --git a/src/frontend/src/types/utils/typeCheckingUtils.ts b/src/frontend/src/types/utils/typeCheckingUtils.ts new file mode 100644 index 000000000..4173788a8 --- /dev/null +++ b/src/frontend/src/types/utils/typeCheckingUtils.ts @@ -0,0 +1,23 @@ +import { ErrorLogType } from "../api"; + +export function isErrorLogType(value: any): value is ErrorLogType { + return ( + typeof value === "object" && + value !== null && + "errorMessage" in value && + typeof value.errorMessage === "string" && + "stackTrace" in value && + typeof value.stackTrace === "string" + ); +} + +export function isErrorLog( + log: any, +): log is { type: "error"; message: ErrorLogType } { + return ( + typeof log === "object" && + log !== null && + (log.type === "error" || log.type === "ValueError") && + isErrorLogType(log.message) + ); +} diff --git a/src/frontend/src/utils/buildUtils.ts b/src/frontend/src/utils/buildUtils.ts index 71bf4618c..01bb94c4e 100644 --- a/src/frontend/src/utils/buildUtils.ts +++ b/src/frontend/src/utils/buildUtils.ts @@ -5,6 +5,7 @@ import { getVerticesOrder, postBuildVertex } from "../controllers/API"; import useAlertStore from "../stores/alertStore"; import useFlowStore from "../stores/flowStore"; import { VertexBuildTypeAPI } from "../types/api"; +import { isErrorLogType } from "../types/utils/typeCheckingUtils"; import { VertexLayerElementType } from "../types/zustand/flow"; type BuildVerticesParams = { @@ -275,9 +276,14 @@ async function buildVertex({ const errorMessages = Object.keys(buildData.data.logs).map((key) => { const logs = buildData.data.logs[key]; if (Array.isArray(logs)) { - return logs.map((log) => log.message); + return logs + .filter((log) => isErrorLogType(log.message)) + .map((log) => log.message.errorMessage); } - return [logs.message]; + if (!isErrorLogType(logs.message)) { + return []; + } + return [logs.message.errorMessage]; }); onBuildError!( "Error Building Component",