fix: display errors when webhook background tasks fail (#7572)
* 📝 (base.py): improve naming convention for task names in Graph class 🔧 (base.py): add error logging functionality in _execute_tasks method 🔧 (utils.py): update data parameter type in log_vertex_build function 🔧 (index.tsx): remove unused setCurrentFlow function call in StoreCardComponent 🔧 (use-get-builds-polling-mutation.ts): add error handling and display logic for build failures 🔧 (flowSidebarComponent/index.tsx): make showLegacy prop optional in FlowSidebarComponentProps interface 🔧 (index.tsx): remove commented out code related to branding in FlowPage component * [autofix.ci] apply automated fixes * fix: update URL construction in CopyFieldAreaComponent to handle undefined endpointName - Modified the URL construction logic to use currentFlow.id when endpointName is not provided, ensuring a valid URL is always generated. * 🔧 (base.py): add error logging method for vertex build failures - Introduced `_log_vertex_build_from_exception` method to handle and log exceptions during vertex building, improving error reporting and output structure. - Updated `_execute_tasks` method to utilize the new logging method for better exception handling. * 🐛 (use-get-builds-polling-mutation.ts): fix error display count to only show errors once per build failure instead of multiple times * 📝 (embedding_model.py): improve formatting of the info message for the 'dimensions' input to enhance readability and clarity * [autofix.ci] apply automated fixes * fix: add webhook component handling in task execution --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
This commit is contained in:
parent
c34b30718e
commit
eed7dee8bf
7 changed files with 114 additions and 62 deletions
|
|
@ -196,45 +196,6 @@ export default function StoreCardComponent({
|
|||
<CardFooter>
|
||||
<div className="z-50 flex w-full items-center justify-between gap-2">
|
||||
<div className="flex w-full flex-wrap items-end justify-end gap-2">
|
||||
{/* {playground && (
|
||||
<Button
|
||||
disabled={loadingPlayground || !authorized}
|
||||
key={data.id}
|
||||
tabIndex={-1}
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="z-50 gap-2 whitespace-nowrap"
|
||||
data-testid={"playground-flow-button-" + data.id}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setLoadingPlayground(true);
|
||||
getFlowData().then((res) => {
|
||||
if (!hasPlayground(res)) {
|
||||
setErrorData({
|
||||
title: "Error",
|
||||
list: ["This flow doesn't have a playground."],
|
||||
});
|
||||
setLoadingPlayground(false);
|
||||
return;
|
||||
}
|
||||
setCurrentFlow(res);
|
||||
setOpenPlayground(true);
|
||||
setLoadingPlayground(false);
|
||||
});
|
||||
}}
|
||||
>
|
||||
{!loadingPlayground ? (
|
||||
<IconComponent
|
||||
name="BotMessageSquareIcon"
|
||||
className="h-4 w-4 select-none"
|
||||
/>
|
||||
) : (
|
||||
<Loading className="h-4 w-4 text-medium-indigo" />
|
||||
)}
|
||||
Playground
|
||||
</Button>
|
||||
)} */}
|
||||
<div className="flex gap-0.5">
|
||||
<ShadTooltip
|
||||
content={authorized ? "Like" : "Please review your API key."}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@ export default function CopyFieldAreaComponent({
|
|||
const [isFocused, setIsFocused] = useState(false);
|
||||
const [isCopied, setIsCopied] = useState(false);
|
||||
|
||||
const isValueToReplace = value === BACKEND_URL || value === MCP_SSE_VALUE;
|
||||
const setSuccessData = useAlertStore((state) => state.setSuccessData);
|
||||
const currentFlow = useFlowStore((state) => state.currentFlow);
|
||||
const endpointName = currentFlow?.endpoint_name ?? "";
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import useAlertStore from "@/stores/alertStore";
|
||||
import useFlowStore from "@/stores/flowStore";
|
||||
import { useUtilityStore } from "@/stores/utilityStore";
|
||||
import { useMutationFunctionType } from "@/types/api";
|
||||
|
|
@ -7,6 +8,9 @@ import { api } from "../../api";
|
|||
import { getURL } from "../../helpers/constants";
|
||||
import { UseRequestProcessor } from "../../services/request-processor";
|
||||
|
||||
const ERROR_DISPLAY_INTERVAL = 10000;
|
||||
const ERROR_DISPLAY_COUNT = 1;
|
||||
|
||||
interface PollingItem {
|
||||
interval: NodeJS.Timeout;
|
||||
timestamp: number;
|
||||
|
|
@ -96,6 +100,10 @@ export const useGetBuildsMutation: useMutationFunctionType<
|
|||
|
||||
const flowIdRef = useRef<string | null>(null);
|
||||
const requestInProgressRef = useRef<Record<string, boolean>>({});
|
||||
const errorDisplayCountRef = useRef<number>(0);
|
||||
const timeoutIdsRef = useRef<number[]>([]);
|
||||
|
||||
const setErrorData = useAlertStore((state) => state.setErrorData);
|
||||
|
||||
const getBuildsFn = async (
|
||||
payload: IGetBuilds,
|
||||
|
|
@ -115,6 +123,24 @@ export const useGetBuildsMutation: useMutationFunctionType<
|
|||
if (Object.keys(flowPool).length > 0) {
|
||||
setFlowPool(flowPool);
|
||||
}
|
||||
|
||||
// Check for errors only if we haven't displayed them yet
|
||||
if (errorDisplayCountRef.current === 0) {
|
||||
Object.keys(flowPool).forEach((key) => {
|
||||
const nodeBuild = flowPool[key];
|
||||
if (nodeBuild.length > 0 && nodeBuild[0]?.valid === false) {
|
||||
const errorMessage = nodeBuild?.[0]?.params || "Unknown error";
|
||||
if (errorMessage) {
|
||||
setErrorData({
|
||||
title: "Last build failed",
|
||||
list: [errorMessage],
|
||||
});
|
||||
errorDisplayCountRef.current = 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -145,9 +171,9 @@ export const useGetBuildsMutation: useMutationFunctionType<
|
|||
const timestamp = Date.now();
|
||||
const pollCallback = async () => {
|
||||
const data = await getBuildsFn(payload);
|
||||
payload.onSuccess?.(data);
|
||||
payload.onSuccess?.(data!);
|
||||
|
||||
if (payload.stopPollingOn?.(data)) {
|
||||
if (payload.stopPollingOn?.(data!)) {
|
||||
PollingManager.stopPoll(payload.flowId);
|
||||
}
|
||||
};
|
||||
|
|
@ -164,8 +190,8 @@ export const useGetBuildsMutation: useMutationFunctionType<
|
|||
PollingManager.enqueuePolling(payload.flowId, pollingItem);
|
||||
|
||||
return getBuildsFn(payload).then((data) => {
|
||||
payload.onSuccess?.(data);
|
||||
if (payload.stopPollingOn?.(data)) {
|
||||
payload.onSuccess?.(data!);
|
||||
if (payload.stopPollingOn?.(data!)) {
|
||||
PollingManager.stopPoll(payload.flowId);
|
||||
}
|
||||
});
|
||||
|
|
@ -176,6 +202,13 @@ export const useGetBuildsMutation: useMutationFunctionType<
|
|||
if (flowIdRef.current) {
|
||||
PollingManager.stopPoll(flowIdRef.current);
|
||||
}
|
||||
// Clear all timeouts
|
||||
timeoutIdsRef.current.forEach((timeoutId) => {
|
||||
clearTimeout(timeoutId);
|
||||
});
|
||||
timeoutIdsRef.current = [];
|
||||
// Reset error display count when component unmounts
|
||||
errorDisplayCountRef.current = 0;
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
|
|
|||
|
|
@ -172,17 +172,6 @@ export default function FlowPage({ view }: { view?: boolean }): JSX.Element {
|
|||
</SidebarProvider>
|
||||
</div>
|
||||
)}
|
||||
{/* {ENABLE_BRANDING && version && (
|
||||
<a
|
||||
target={"_blank"}
|
||||
href="https://medium.com/logspace/langflow-datastax-better-together-1b7462cebc4d"
|
||||
className="langflow-page-icon"
|
||||
>
|
||||
<div className="mt-1">Langflow 🤝 DataStax</div>
|
||||
|
||||
<div className={version ? "mt-2" : "mt-1"}>⛓️ v{version}</div>
|
||||
</a>
|
||||
)} */}
|
||||
</div>
|
||||
{blocker.state === "blocked" && (
|
||||
<>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue