Catch exceptions and log instead of crashing (#6477)
* Catch exceptions and log instead of crashing Modified both WorkflowInstance and WorkflowDefinition state loading to prevent throwing exceptions if the state fails to load successfully. Also modified the CleanupJob to catch exceptions thrown by cleaning up and logging as errors and continuing instead of crashing. Fixes 6473 * Use LogError instead of LogWarning for deserialization failure. Updated the log level to LogError when workflow definition state deserialization fails. This change ensures better visibility and prioritization of critical issues during state handling. --------- Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
This commit is contained in:
parent
8e9d5e356e
commit
aa989ce13d
|
|
@ -13,12 +13,13 @@ using Elsa.Common.Entities;
|
|||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Management;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Elsa.EntityFrameworkCore.Modules.Management;
|
||||
|
||||
/// <inheritdoc />
|
||||
[UsedImplicitly]
|
||||
public class EFCoreWorkflowDefinitionStore(EntityStore<ManagementElsaDbContext, WorkflowDefinition> store, IPayloadSerializer payloadSerializer)
|
||||
public class EFCoreWorkflowDefinitionStore(EntityStore<ManagementElsaDbContext, WorkflowDefinition> store, IPayloadSerializer payloadSerializer, ILogger<EFCoreWorkflowDefinitionStore> logger)
|
||||
: IWorkflowDefinitionStore
|
||||
{
|
||||
/// <inheritdoc />
|
||||
|
|
@ -178,8 +179,15 @@ public class EFCoreWorkflowDefinitionStore(EntityStore<ManagementElsaDbContext,
|
|||
var data = new WorkflowDefinitionState(entity.Options, entity.Variables, entity.Inputs, entity.Outputs, entity.Outcomes, entity.CustomProperties);
|
||||
var json = (string?)managementElsaDbContext.Entry(entity).Property("Data").CurrentValue;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(json))
|
||||
data = payloadSerializer.Deserialize<WorkflowDefinitionState>(json);
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(json))
|
||||
data = payloadSerializer.Deserialize<WorkflowDefinitionState>(json);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
logger.LogError(exp, "Could not deserialize workflow definition state: {DefinitionId}. Reverting to default state", entity.DefinitionId);
|
||||
}
|
||||
|
||||
entity.Options = data.Options;
|
||||
entity.Variables = data.Variables;
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ using Elsa.Workflows.Management.Models;
|
|||
using Elsa.Workflows.Management.Options;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Open.Linq.AsyncExtensions;
|
||||
|
||||
|
|
@ -26,6 +27,7 @@ public class EFCoreWorkflowInstanceStore : IWorkflowInstanceStore
|
|||
private readonly IWorkflowStateSerializer _workflowStateSerializer;
|
||||
private readonly ICompressionCodecResolver _compressionCodecResolver;
|
||||
private readonly IOptions<ManagementOptions> _options;
|
||||
private readonly ILogger<EFCoreWorkflowInstanceStore> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor.
|
||||
|
|
@ -34,12 +36,14 @@ public class EFCoreWorkflowInstanceStore : IWorkflowInstanceStore
|
|||
EntityStore<ManagementElsaDbContext, WorkflowInstance> store,
|
||||
IWorkflowStateSerializer workflowStateSerializer,
|
||||
ICompressionCodecResolver compressionCodecResolver,
|
||||
IOptions<ManagementOptions> options)
|
||||
IOptions<ManagementOptions> options,
|
||||
ILogger<EFCoreWorkflowInstanceStore> logger)
|
||||
{
|
||||
_store = store;
|
||||
_workflowStateSerializer = workflowStateSerializer;
|
||||
_compressionCodecResolver = compressionCodecResolver;
|
||||
_options = options;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
@ -236,12 +240,18 @@ public class EFCoreWorkflowInstanceStore : IWorkflowInstanceStore
|
|||
var compressionAlgorithm = (string?)managementElsaDbContext.Entry(entity).Property("DataCompressionAlgorithm").CurrentValue ?? nameof(None);
|
||||
var compressionStrategy = _compressionCodecResolver.Resolve(compressionAlgorithm);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(json))
|
||||
try
|
||||
{
|
||||
json = await compressionStrategy.DecompressAsync(json, cancellationToken);
|
||||
data = _workflowStateSerializer.Deserialize(json);
|
||||
if (!string.IsNullOrWhiteSpace(json))
|
||||
{
|
||||
json = await compressionStrategy.DecompressAsync(json, cancellationToken);
|
||||
data = _workflowStateSerializer.Deserialize(json);
|
||||
}
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
_logger.LogWarning(exp, "Exception while deserializing workflow instance state: {InstanceId}. Reverting to default state", entity.Id);
|
||||
}
|
||||
|
||||
entity.WorkflowState = data;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,7 +71,14 @@ public class CleanupJob(
|
|||
|
||||
await foreach (var entities in collector.GetRelatedEntitiesGeneric(page.Items).WithCancellation(cancellationToken))
|
||||
{
|
||||
await cleanupService.Cleanup(entities);
|
||||
try
|
||||
{
|
||||
await cleanupService.Cleanup(entities);
|
||||
}
|
||||
catch (Exception exp)
|
||||
{
|
||||
_logger.LogError(exp, "Failed to clean up {Type} because exception thrown", collectorService.Key.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue