From 136721241275c6c2d08bbdc62de553b2702760c0 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 19 Jun 2024 12:24:02 -0300 Subject: [PATCH] refactor: Update LogType to include ErrorLogType The LogType in the schema module has been updated to include the ErrorLogType. This allows for more detailed logging of error messages, including the error message itself and the stack trace. This change improves the accuracy and usefulness of error logging in the application. --- src/backend/base/langflow/api/v1/chat.py | 7 ++++-- src/backend/base/langflow/graph/graph/base.py | 2 +- .../base/langflow/graph/vertex/base.py | 9 +++----- src/backend/base/langflow/schema/schema.py | 10 ++++++-- .../components/switchOutputView/index.tsx | 4 +++- .../components/parameterComponent/index.tsx | 12 +++------- .../hooks/use-validation-status-string.tsx | 8 +++---- src/frontend/src/types/api/index.ts | 7 +++++- .../src/types/utils/typeCheckingUtils.ts | 23 +++++++++++++++++++ src/frontend/src/utils/buildUtils.ts | 10 ++++++-- 10 files changed, 64 insertions(+), 28 deletions(-) create mode 100644 src/frontend/src/types/utils/typeCheckingUtils.ts 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",