diff --git a/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeHarvester.cs b/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeHarvester.cs
index f418ff2b5d6..3099fd3db77 100644
--- a/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeHarvester.cs
+++ b/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeHarvester.cs
@@ -32,7 +32,7 @@ public RecipeHarvester(
///
public virtual Task> HarvestRecipesAsync()
- => _extensionManager.GetExtensions().InvokeAsync(HarvestRecipes, _logger);
+ => _extensionManager.GetExtensions().InvokeAsync(GetRecipesAsync, _logger);
///
/// Returns a list of recipes for a content path.
@@ -50,13 +50,18 @@ protected async Task> HarvestRecipesAsync(string p
{
var recipeDescriptor = await _recipeReader.GetRecipeDescriptorAsync(path, recipeFile, _hostingEnvironment.ContentRootFileProvider);
+ if (recipeDescriptor == null)
+ {
+ continue;
+ }
+
recipeDescriptors.Add(recipeDescriptor);
}
return recipeDescriptors;
}
- private Task> HarvestRecipes(IExtensionInfo extension)
+ private Task> GetRecipesAsync(IExtensionInfo extension)
{
var folderSubPath = PathExtensions.Combine(extension.SubPath, RecipesConstants.RecipesFolderName);
diff --git a/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeMigrator.cs b/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeMigrator.cs
index 2ae164a9897..91215655429 100644
--- a/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeMigrator.cs
+++ b/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeMigrator.cs
@@ -45,14 +45,23 @@ public async Task ExecuteAsync(string recipeFileName, IDataMigration mig
var recipeFilePath = Path.Combine(recipeBasePath, recipeFileName).Replace('\\', '/');
var recipeFileInfo = _hostingEnvironment.ContentRootFileProvider.GetFileInfo(recipeFilePath);
var recipeDescriptor = await _recipeReader.GetRecipeDescriptorAsync(recipeBasePath, recipeFileInfo, _hostingEnvironment.ContentRootFileProvider);
+
+ if (recipeDescriptor == null)
+ {
+ return null;
+ }
+
recipeDescriptor.RequireNewScope = false;
var environment = new Dictionary();
- await _environmentProviders.OrderBy(x => x.Order).InvokeAsync((provider, env) => provider.PopulateEnvironmentAsync(env), environment, _logger);
+ await _environmentProviders.OrderBy(x => x.Order)
+ .InvokeAsync((provider, env) => provider.PopulateEnvironmentAsync(env), environment, _logger);
var executionId = Guid.NewGuid().ToString("n");
+
return await _recipeExecutor.ExecuteAsync(executionId, recipeDescriptor, environment, CancellationToken.None);
}
}
}
+
diff --git a/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeReader.cs b/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeReader.cs
index 5a718e854f2..a922d33b3e1 100644
--- a/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeReader.cs
+++ b/src/OrchardCore/OrchardCore.Recipes.Core/Services/RecipeReader.cs
@@ -1,22 +1,41 @@
+using System;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Extensions.FileProviders;
+using Microsoft.Extensions.Logging;
using OrchardCore.Recipes.Models;
namespace OrchardCore.Recipes.Services
{
public class RecipeReader : IRecipeReader
{
+ private readonly ILogger _logger;
+
+ public RecipeReader(ILogger logger)
+ {
+ _logger = logger;
+ }
+
public async Task GetRecipeDescriptorAsync(string recipeBasePath, IFileInfo recipeFileInfo, IFileProvider recipeFileProvider)
{
// TODO: Try to optimize by only reading the required metadata instead of the whole file.
using var stream = recipeFileInfo.CreateReadStream();
- var recipeDescriptor = await JsonSerializer.DeserializeAsync(stream, JOptions.Default);
+ RecipeDescriptor recipeDescriptor = null;
+
+ try
+ {
+ recipeDescriptor = await JsonSerializer.DeserializeAsync(stream, JOptions.Default);
+
+ recipeDescriptor.FileProvider = recipeFileProvider;
+ recipeDescriptor.BasePath = recipeBasePath;
+ recipeDescriptor.RecipeFileInfo = recipeFileInfo;
- recipeDescriptor.FileProvider = recipeFileProvider;
- recipeDescriptor.BasePath = recipeBasePath;
- recipeDescriptor.RecipeFileInfo = recipeFileInfo;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Unable to deserialize the recipe file: '{FileName}'.", recipeFileInfo.Name);
+ }
return recipeDescriptor;
}
diff --git a/test/OrchardCore.Tests/Apis/Context/TestRecipeHarvester.cs b/test/OrchardCore.Tests/Apis/Context/TestRecipeHarvester.cs
index 9f7803f376f..19bef681e49 100644
--- a/test/OrchardCore.Tests/Apis/Context/TestRecipeHarvester.cs
+++ b/test/OrchardCore.Tests/Apis/Context/TestRecipeHarvester.cs
@@ -37,6 +37,12 @@ private async Task> HarvestRecipesAsync(string[] p
foreach (var fileInfo in fileInfos)
{
var descriptor = await _recipeReader.GetRecipeDescriptorAsync(fileInfo.PhysicalPath, fileInfo, testAssemblyFileProvider);
+
+ if (descriptor == null)
+ {
+ continue;
+ }
+
recipeDescriptors.Add(descriptor);
}