From 6097ba0c9e095fa6a492776806df6f68e4cfdc3c Mon Sep 17 00:00:00 2001 From: Mike Alhayek Date: Wed, 29 May 2024 20:58:37 -0700 Subject: [PATCH] Simplify error handling in recipe execution --- .../Controllers/ImportRemoteInstanceController.cs | 2 +- .../Controllers/ImportController.cs | 5 ++--- .../OrchardCore.Recipes/Controllers/AdminController.cs | 2 +- .../Models/RecipeStepResult.cs | 4 +--- .../Services/RecipeExecutor.cs | 10 ++-------- src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs | 2 +- test/OrchardCore.Tests/Recipes/RecipeExecutorTests.cs | 2 +- 7 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Deployment.Remote/Controllers/ImportRemoteInstanceController.cs b/src/OrchardCore.Modules/OrchardCore.Deployment.Remote/Controllers/ImportRemoteInstanceController.cs index 4f000fb87a1..b0cacb21222 100644 --- a/src/OrchardCore.Modules/OrchardCore.Deployment.Remote/Controllers/ImportRemoteInstanceController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Deployment.Remote/Controllers/ImportRemoteInstanceController.cs @@ -93,7 +93,7 @@ public async Task Import(ImportViewModel model) { _logger.LogError(e, "Unable to import a recipe from deployment plan."); - await _notifier.ErrorAsync(H["The deployment plan failed with the following errors: {0}", string.Join(' ', e.StepResult.Errors.SelectMany(x => x.Value))]); + await _notifier.ErrorAsync(H["The deployment plan failed with the following errors: {0}", string.Join(' ', e.StepResult.Errors)]); } catch (Exception e) { diff --git a/src/OrchardCore.Modules/OrchardCore.Deployment/Controllers/ImportController.cs b/src/OrchardCore.Modules/OrchardCore.Deployment/Controllers/ImportController.cs index 3d68c8bc214..8d794abc666 100644 --- a/src/OrchardCore.Modules/OrchardCore.Deployment/Controllers/ImportController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Deployment/Controllers/ImportController.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.IO.Compression; -using System.Linq; using System.Text.Json; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; @@ -102,7 +101,7 @@ public async Task Import(IFormFile importedPackage) { _logger.LogError(e, "Unable to import a deployment package."); - await _notifier.ErrorAsync(H["The import failed with the following errors: {0}", string.Join(' ', e.StepResult.Errors.SelectMany(x => x.Value))]); + await _notifier.ErrorAsync(H["The import failed with the following errors: {0}", string.Join(' ', e.StepResult.Errors)]); } catch (Exception e) { @@ -171,7 +170,7 @@ public async Task Json(ImportJsonViewModel model) { _logger.LogError(e, "Unable to import a recipe from JSON input."); - ModelState.AddModelError(nameof(model.Json), string.Join(' ', e.StepResult.Errors.SelectMany(x => x.Value))); + ModelState.AddModelError(nameof(model.Json), string.Join(' ', e.StepResult.Errors)); } catch (Exception e) { diff --git a/src/OrchardCore.Modules/OrchardCore.Recipes/Controllers/AdminController.cs b/src/OrchardCore.Modules/OrchardCore.Recipes/Controllers/AdminController.cs index 3f723c99e40..401a534ce9c 100644 --- a/src/OrchardCore.Modules/OrchardCore.Recipes/Controllers/AdminController.cs +++ b/src/OrchardCore.Modules/OrchardCore.Recipes/Controllers/AdminController.cs @@ -124,7 +124,7 @@ public async Task Execute(string basePath, string fileName) { _logger.LogError(e, "Unable to import a recipe file."); - await _notifier.ErrorAsync(H["The recipe '{0}' failed to run do to the following errors: {1}", recipe.DisplayName, string.Join(' ', e.StepResult.Errors.SelectMany(x => x.Value))]); + await _notifier.ErrorAsync(H["The recipe '{0}' failed to run do to the following errors: {1}", recipe.DisplayName, string.Join(' ', e.StepResult.Errors)]); } catch (Exception e) { diff --git a/src/OrchardCore/OrchardCore.Recipes.Abstractions/Models/RecipeStepResult.cs b/src/OrchardCore/OrchardCore.Recipes.Abstractions/Models/RecipeStepResult.cs index e194f44c92f..8190dd84dec 100644 --- a/src/OrchardCore/OrchardCore.Recipes.Abstractions/Models/RecipeStepResult.cs +++ b/src/OrchardCore/OrchardCore.Recipes.Abstractions/Models/RecipeStepResult.cs @@ -1,5 +1,3 @@ -using System.Collections.Generic; - namespace OrchardCore.Recipes.Models; public class RecipeStepResult @@ -10,5 +8,5 @@ public class RecipeStepResult public bool IsSuccessful { get; set; } - public Dictionary Errors { get; set; } + public string[] Errors { get; set; } } diff --git a/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeExecutor.cs b/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeExecutor.cs index 394e46baad5..5d1ba0eca83 100644 --- a/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeExecutor.cs +++ b/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeExecutor.cs @@ -105,10 +105,7 @@ public async Task ExecuteAsync(string executionId, RecipeDescriptor reci if (recipeStep.Errors.Count > 0) { stepResult.IsSuccessful = false; - stepResult.Errors = new Dictionary - { - { recipeStep.Name, recipeStep.Errors.ToArray() } - }; + stepResult.Errors = recipeStep.Errors.ToArray(); } else { @@ -118,10 +115,7 @@ public async Task ExecuteAsync(string executionId, RecipeDescriptor reci catch (Exception e) { stepResult.IsSuccessful = false; - stepResult.Errors = new Dictionary - { - { recipeStep.Name, [S["Unexpected error occurred while executing the '{0}' step.", stepResult.StepName]] } - }; + stepResult.Errors = [S["Unexpected error occurred while executing the '{0}' step.", stepResult.StepName]]; // Because we can't do some async processing the in catch or finally // blocks, we store the exception to throw it later. diff --git a/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs b/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs index bb9b81198b4..ff70e897cf6 100644 --- a/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs +++ b/src/OrchardCore/OrchardCore.Setup.Core/SetupService.cs @@ -235,7 +235,7 @@ await scope.ServiceProvider.GetService() { _logger.LogError(e, "Unable to import a recipe during setup."); - context.Errors.Add(string.Empty, string.Join(' ', e.StepResult.Errors.SelectMany(x => x.Value))); + context.Errors.Add(string.Empty, string.Join(' ', e.StepResult.Errors)); } catch (Exception e) { diff --git a/test/OrchardCore.Tests/Recipes/RecipeExecutorTests.cs b/test/OrchardCore.Tests/Recipes/RecipeExecutorTests.cs index a673c7b9f59..7ef6968115b 100644 --- a/test/OrchardCore.Tests/Recipes/RecipeExecutorTests.cs +++ b/test/OrchardCore.Tests/Recipes/RecipeExecutorTests.cs @@ -73,7 +73,7 @@ await context.UsingTenantScopeAsync(async scope => await recipeExecutor.ExecuteAsync(executionId, recipeDescriptor, new Dictionary(), CancellationToken.None); }); - Assert.Contains("Unable to add content-part to the 'Message' content-type. The part name cannot be null or empty.", exception.StepResult.Errors["ContentDefinition"]); + Assert.Contains("Unable to add content-part to the 'Message' content-type. The part name cannot be null or empty.", exception.StepResult.Errors); }); }