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.
This commit is contained in:
Gabriel Luiz Freitas Almeida 2024-06-19 12:24:02 -03:00
commit 1367212412
10 changed files with 64 additions and 28 deletions

View file

@ -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

View file

@ -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

View file

@ -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):
"""

View file

@ -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

View file

@ -41,7 +41,9 @@ const SwitchOutputView: React.FC<SwitchOutputViewProps> = ({
<div>NO OUTPUT</div>
</Case>
<Case condition={resultType === "error" || resultType === "ValueError"}>
<ErrorOutput value={resultMessage}></ErrorOutput>
<ErrorOutput
value={`${resultMessage.errorMessage}\n\n${resultMessage.stackTrace}`}
></ErrorOutput>
</Case>
<Case condition={node && resultType === "text"}>

View file

@ -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);

View file

@ -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);

View file

@ -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;
};

View file

@ -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)
);
}

View file

@ -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",