diff --git a/amber/src/main/scala/org/apache/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala b/amber/src/main/scala/org/apache/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala index 6fbd19bcc2c..28d232c867e 100644 --- a/amber/src/main/scala/org/apache/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala +++ b/amber/src/main/scala/org/apache/texera/web/resource/dashboard/user/workflow/WorkflowResource.scala @@ -959,6 +959,9 @@ class WorkflowResource extends LazyLogging { .where(WORKFLOW.WID.eq(wid)) .and(WORKFLOW.IS_PUBLIC.isTrue) .fetchOne() + if (workflow == null) { + throw new NotFoundException(s"Public workflow with id $wid not found") + } // Name and description come from the public copy for the same reason as the content: a pin has // to hold everything on show. val publicCopy = WorkflowPublishService.publicCopyOf(workflow.into(classOf[Workflow])) diff --git a/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala b/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala index 24cbf8da2aa..57616afc72a 100644 --- a/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala +++ b/amber/src/test/scala/org/apache/texera/web/resource/dashboard/file/WorkflowResourceSpec.scala @@ -1006,6 +1006,16 @@ class WorkflowResourceSpec assertThrows[ForbiddenException](workflowResource.makePublic(wid, sessionUser2)) } + "WorkflowResource.retrievePublicWorkflow" should "throw NotFoundException for a private workflow" in { + val wid = seedWorkflow(sessionUser1, "public-private-wf").workflow.getWid + assertThrows[NotFoundException](workflowResource.retrievePublicWorkflow(wid)) + } + + it should "throw NotFoundException for a wid that does not exist" in { + val wid = seedWorkflow(sessionUser1, "public-missing-wf").workflow.getWid + assertThrows[NotFoundException](workflowResource.retrievePublicWorkflow(wid + 100000)) + } + "WorkflowResource.duplicateWorkflow" should "create a distinct copy owned by the user" in { // duplicateWorkflow reassigns operator ids, so the content must have an operators array. val wid = seedWorkflow(