diff --git a/CHANGELOG.md b/CHANGELOG.md index b9a43513d6..7165b43afe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,9 @@ and this project adheres to project is opt-in. [#4919](https://github.com/OpenFn/lightning/issues/4919) - Fixed an issue where LOCAL_ADAPTORS is not respected by install_schemas task [#4943](https://github.com/OpenFn/lightning/issues/4943) +- Return clean API errors when a workflow is deleted during save or its snapshot + cannot be saved, instead of allowing the workflows controller to crash. + [#4960](https://github.com/OpenFn/lightning/issues/4960) - Prevent AI Assistant channel joins from crashing when a chat references a deleted workflow or project. Missing records now fail authorization cleanly. [#4914](https://github.com/OpenFn/lightning/issues/4914) diff --git a/lib/lightning_web/controllers/api/workflows_controller.ex b/lib/lightning_web/controllers/api/workflows_controller.ex index f42bca7b9d..ada539493d 100644 --- a/lib/lightning_web/controllers/api/workflows_controller.ex +++ b/lib/lightning_web/controllers/api/workflows_controller.ex @@ -562,6 +562,19 @@ defmodule LightningWeb.API.WorkflowsController do |> json(%{id: workflow_id, errors: ["Not Found"]}) end + defp maybe_handle_error(conn, {:error, :workflow_deleted}, workflow_id), + do: maybe_handle_error(conn, {:error, :not_found}, workflow_id) + + defp maybe_handle_error(conn, {:error, reason}, workflow_id) + when reason in [:snapshot_failed, false] do + conn + |> put_status(:internal_server_error) + |> json(%{ + id: workflow_id, + errors: ["Could not save the workflow snapshot."] + }) + end + defp maybe_handle_error(_conn, result, _workflow_id) when is_map(result), do: result diff --git a/test/lightning_web/controllers/api/workflows_controller_test.exs b/test/lightning_web/controllers/api/workflows_controller_test.exs index 62378626a7..e2d4ed7974 100644 --- a/test/lightning_web/controllers/api/workflows_controller_test.exs +++ b/test/lightning_web/controllers/api/workflows_controller_test.exs @@ -998,6 +998,55 @@ defmodule LightningWeb.API.WorkflowsControllerTest do |> json_response(404) end + test "returns 404 when the workflow is deleted before update", %{ + conn: conn, + project: project + } do + workflow = insert(:simple_workflow, project: project) + + workflow = + workflow + |> Ecto.Changeset.change( + deleted_at: DateTime.utc_now() |> DateTime.truncate(:second) + ) + |> Repo.update!() + + assert %{"id" => workflow_id, "errors" => ["Not Found"]} = + conn + |> patch( + ~p"/api/projects/#{project.id}/workflows/#{workflow.id}", + Jason.encode!(%{name: "work1.1"}) + ) + |> json_response(404) + + assert workflow_id == workflow.id + end + + test "returns 500 when the workflow snapshot cannot be saved", %{ + conn: conn, + project: project + } do + workflow = insert(:simple_workflow, project: project) + + insert(:snapshot, + workflow: workflow, + lock_version: workflow.lock_version + 1 + ) + + assert %{ + "id" => workflow_id, + "errors" => ["Could not save the workflow snapshot."] + } = + conn + |> patch( + ~p"/api/projects/#{project.id}/workflows/#{workflow.id}", + Jason.encode!(%{name: "work1.1"}) + ) + |> json_response(500) + + assert workflow_id == workflow.id + end + test "returns 409 when the workflow is being edited on the UI" do %{conn: conn, user: user} = register_and_log_in_user(%{conn: Phoenix.ConnTest.build_conn()})