Surface publish validation warnings on API responses
In lenient mode (FailOnValidationErrors = false), PublishAsync returns Succeeded = true while ValidationErrors may still be non-empty. Previously the publish API endpoints discarded those warnings, so lenient-mode callers got a 200 OK with no indication of the validation issues. - Publish and Post (save-and-publish) responses now include a ValidationErrors collection populated with the publish result's validation messages. - BulkPublish response now includes a Warnings dictionary mapping each successfully-published definition id to its validation warning messages. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
354d59942c
commit
2863c980f3
|
|
@ -42,6 +42,7 @@ internal class BulkPublish(
|
|||
var skipped = new List<string>();
|
||||
var updatedConsumers = new List<string>();
|
||||
var failed = new List<string>();
|
||||
var warnings = new Dictionary<string, ICollection<string>>();
|
||||
var publishableDefinitions = new List<(string DefinitionId, WorkflowDefinition Definition)>();
|
||||
|
||||
var definitions = (await store.FindManyAsync(new WorkflowDefinitionFilter
|
||||
|
|
@ -97,12 +98,15 @@ internal class BulkPublish(
|
|||
}
|
||||
|
||||
published.Add(definitionId);
|
||||
|
||||
if (result.ValidationErrors.Count > 0)
|
||||
warnings[definitionId] = result.ValidationErrors.Select(x => x.Message).ToList();
|
||||
|
||||
if (result.AffectedWorkflows.WorkflowDefinitions.Count > 0)
|
||||
updatedConsumers.AddRange(result.AffectedWorkflows.WorkflowDefinitions.Select(x => x.DefinitionId));
|
||||
}
|
||||
|
||||
return new(published, alreadyPublished, notFound, skipped, updatedConsumers, failed);
|
||||
return new(published, alreadyPublished, notFound, skipped, updatedConsumers, failed, warnings);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ internal class Request
|
|||
public ICollection<string> DefinitionIds { get; set; } = default!;
|
||||
}
|
||||
|
||||
internal class Response(ICollection<string> published, ICollection<string> alreadyPublished, ICollection<string> notFound, ICollection<string> skipped, ICollection<string> updatedConsumers, ICollection<string> failed)
|
||||
internal class Response(ICollection<string> published, ICollection<string> alreadyPublished, ICollection<string> notFound, ICollection<string> skipped, ICollection<string> updatedConsumers, ICollection<string> failed, IDictionary<string, ICollection<string>> warnings)
|
||||
{
|
||||
public ICollection<string> Published { get; } = published;
|
||||
public ICollection<string> AlreadyPublished { get; } = alreadyPublished;
|
||||
|
|
@ -13,4 +13,5 @@ internal class Response(ICollection<string> published, ICollection<string> alrea
|
|||
public ICollection<string> Skipped { get; } = skipped;
|
||||
public ICollection<string> UpdatedConsumers { get; } = updatedConsumers;
|
||||
public ICollection<string> Failed { get; } = failed;
|
||||
public IDictionary<string, ICollection<string>> Warnings { get; } = warnings;
|
||||
}
|
||||
|
|
@ -116,7 +116,8 @@ internal class Post(
|
|||
|
||||
var mappedDefinition = await linker.MapAsync(draft, cancellationToken);
|
||||
var affectedWorkflows = result?.AffectedWorkflows?.WorkflowDefinitions ?? [];
|
||||
var response = new Response(mappedDefinition, false, affectedWorkflows.Count);
|
||||
var validationErrors = result?.ValidationErrors.Select(e => e.Message).ToList() ?? [];
|
||||
var response = new Response(mappedDefinition, false, affectedWorkflows.Count, validationErrors);
|
||||
await HttpContext.Response.WriteAsJsonAsync(response, serializerOptions, cancellationToken);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@ using Elsa.Workflows.Api.Models;
|
|||
|
||||
namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.Post;
|
||||
|
||||
internal record Response(LinkedWorkflowDefinitionModel WorkflowDefinition, bool AlreadyPublished, int ConsumingWorkflowCount);
|
||||
internal record Response(LinkedWorkflowDefinitionModel WorkflowDefinition, bool AlreadyPublished, int ConsumingWorkflowCount, ICollection<string> ValidationErrors);
|
||||
|
|
@ -70,8 +70,9 @@ internal class Publish(
|
|||
return;
|
||||
}
|
||||
|
||||
var validationErrors = result?.ValidationErrors.Select(e => e.Message).ToList() ?? [];
|
||||
var mappedDefinition = await linker.MapAsync(definition, cancellationToken);
|
||||
var response = new Response(mappedDefinition, isPublished, result?.AffectedWorkflows.WorkflowDefinitions.Count ?? 0);
|
||||
var response = new Response(mappedDefinition, isPublished, result?.AffectedWorkflows.WorkflowDefinitions.Count ?? 0, validationErrors);
|
||||
await Send.OkAsync(response, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@ internal class Request
|
|||
public string DefinitionId { get; set; } = default!;
|
||||
}
|
||||
|
||||
internal record Response(LinkedWorkflowDefinitionModel WorkflowDefinition, bool AlreadyPublished, int ConsumingWorkflowCount);
|
||||
internal record Response(LinkedWorkflowDefinitionModel WorkflowDefinition, bool AlreadyPublished, int ConsumingWorkflowCount, ICollection<string> ValidationErrors);
|
||||
Loading…
Reference in a new issue