Repository: Significant-Gravitas/Auto-GPT
File: autogpt_platform/frontend/src/hooks/useAgentGraph.tsx (TypeScript)

Code before:
        updateNodesWithExecutionData(data);
        // Execution updates are not cumulative, so we need to filter out the old ones.
        processedUpdates.current = processedUpdates.current.filter(
          (update) => update.node_exec_id !== data.node_exec_id,
        );
        processedUpdates.current.push(data);
      });
      return [];
    });
  }, [updateQueue, nodesSyncedWithSavedAgent, updateNodesWithExecutionData]);

  useEffect(() => {
    if (!flowID || !flowExecutionID) {
      return;
    }

    const fetchExecutions = async () => {
      const execution = await api.getGraphExecutionInfo(
        flowID,
        flowExecutionID,
      );

      // Set graph execution error from the initial fetch
      if (execution.status === "FAILED" && execution.stats?.error) {
        setGraphExecutionError(execution.stats.error);
      }

      if (
        (execution.status === "QUEUED" || execution.status === "RUNNING") &&
        !isRunning
      ) {
        setIsRunning(true);
        setActiveExecutionID(flowExecutionID);
      }
      setUpdateQueue((prev) => {
        if (!execution.node_executions) return prev;
        return [...prev, ...execution.node_executions];
      });

      const cancelGraphExecListener = api.onWebSocketMessage(
        "graph_execution_event",
        (graphExec) => {
          if (graphExec.id != flowExecutionID) {
            return;
          }

          // Update graph execution error state and show toast
          if (graphExec.status === "FAILED" && graphExec?.stats?.error) {
            setGraphExecutionError(graphExec.stats.error);

            if (

Review comment (bug):
In the edge case, we don't have a `stats?. error` returned, I would still set a generic error so it shows up in the UI?

Code after:
        updateNodesWithExecutionData(data);
        // Execution updates are not cumulative, so we need to filter out the old ones.
        processedUpdates.current = processedUpdates.current.filter(
          (update) => update.node_exec_id !== data.node_exec_id,
        );
        processedUpdates.current.push(data);
      });
      return [];
    });
  }, [updateQueue, nodesSyncedWithSavedAgent, updateNodesWithExecutionData]);

  useEffect(() => {
    if (!flowID || !flowExecutionID) {
      return;
    }

    const fetchExecutions = async () => {
      const execution = await api.getGraphExecutionInfo(
        flowID,
        flowExecutionID,
      );

      // Set graph execution error from the initial fetch
      if (execution.status === "FAILED") {
        setGraphExecutionError(
          execution.stats?.error ||
            "The execution failed due to an internal error. You can re-run the agent to retry.",
        );
      }

      if (
        (execution.status === "QUEUED" || execution.status === "RUNNING") &&
        !isRunning
      ) {
        setIsRunning(true);
        setActiveExecutionID(flowExecutionID);
      }
      setUpdateQueue((prev) => {
        if (!execution.node_executions) return prev;
        return [...prev, ...execution.node_executions];
      });

      const cancelGraphExecListener = api.onWebSocketMessage(
        "graph_execution_event",
        (graphExec) => {
          if (graphExec.id != flowExecutionID) {
            return;
          }

          // Update graph execution error state and show toast
          if (graphExec.status === "FAILED") {