Skip to content

Commit

Permalink
Fix deserializer (#123)
Browse files Browse the repository at this point in the history
* try to fix deserializer
  • Loading branch information
coenm authored May 3, 2024
1 parent 5a2186e commit 533b5c1
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 279 deletions.
17 changes: 14 additions & 3 deletions src/RepoM.ActionMenu.Core/ConfigReader/FileReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace RepoM.ActionMenu.Core.ConfigReader;
using System.Linq;
using System.Threading.Tasks;
using DotNetEnv;
using Microsoft.Extensions.Logging;
using RepoM.ActionMenu.Core.Model;
using RepoM.ActionMenu.Core.Yaml.Model;

Expand All @@ -14,11 +15,13 @@ internal class FileReader : IFileReader
private static readonly LoadOptions _loadOptions = new (setEnvVars: false);
private readonly IFileSystem _fileSystem;
private readonly IActionMenuDeserializer _deserializer;
private readonly ILogger _logger;

public FileReader(IFileSystem fileSystem, IActionMenuDeserializer deserializer)
public FileReader(IFileSystem fileSystem, IActionMenuDeserializer deserializer, ILogger logger)
{
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
_deserializer = deserializer ?? throw new ArgumentNullException(nameof(deserializer));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}

public Task<ActionMenuRoot?> DeserializeRoot(string filename)
Expand Down Expand Up @@ -54,7 +57,15 @@ public FileReader(IFileSystem fileSystem, IActionMenuDeserializer deserializer)
return null;
}

var content = await _fileSystem.File.ReadAllTextAsync(filename).ConfigureAwait(false);
return _deserializer.Deserialize<T>(content);
try
{
var content = await _fileSystem.File.ReadAllTextAsync(filename).ConfigureAwait(false);
return _deserializer.Deserialize<T>(content);
}
catch (Exception e)
{
_logger.LogError(e, "Could not deserialize {Filename} as {Type}", filename, typeof(T).Name);
throw;
}
}
}
2 changes: 0 additions & 2 deletions src/RepoM.ActionMenu.Core/Model/IActionMenuDeserializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,5 @@ namespace RepoM.ActionMenu.Core.Model;

internal interface IActionMenuDeserializer
{
string Serialize<T>(T actionMenuRoot) where T : ContextRoot;

T Deserialize<T>(string content) where T : ContextRoot;
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ namespace RepoM.ActionMenu.Core.Yaml.Serialization;
using RepoM.ActionMenu.Interface.YamlModel;
using RepoM.ActionMenu.Interface.YamlModel.Templating;
using RepoM.Core.Plugin.RepositoryOrdering.Configuration;
using YamlDotNet.Core;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.NamingConventions;
Expand All @@ -26,16 +25,15 @@ namespace RepoM.ActionMenu.Core.Yaml.Serialization;
internal class ActionMenuDeserializer : IActionMenuDeserializer
{
private readonly IDeserializer _deserializer;
private readonly ISerializer _serializer;

private readonly ILogger _logger;
private readonly object _syncLock = new();
private static readonly Dictionary<Type, Func<object>> _factoryMethods = new()
{
{ typeof(Script), () => new ScribanScript() },
{ typeof(Variable), () => new ScribanVariable() },
{ typeof(Predicate), () => new ScribanPredicate() },
{ typeof(Text), () => new ScribanText() },
};
private readonly ILogger _logger;

public ActionMenuDeserializer(IEnumerable<IKeyTypeRegistration<IMenuAction>> keyTypeRegistrations, ITemplateParser templateParser, ILogger logger)
: this(keyTypeRegistrations.ToDictionary(item => item.Tag, item => item.ConfigurationType), templateParser, logger)
Expand All @@ -46,15 +44,7 @@ private ActionMenuDeserializer(IDictionary<string, Type> menuActionTypes, ITempl
{
ArgumentNullException.ThrowIfNull(menuActionTypes);
ArgumentNullException.ThrowIfNull(templateParser);
ArgumentNullException.ThrowIfNull(logger);

_logger = logger;

_serializer = new SerializerBuilder()
.WithNamingConvention(HyphenatedNamingConvention.Instance) // CamelCaseNamingConvention.Instance
.WithDefaultScalarStyle(ScalarStyle.Any)
.WithTypeConverter(new EvaluateObjectConverter(_factoryMethods))
.Build();
_logger = logger ?? throw new ArgumentNullException(nameof(logger));

_deserializer = new DeserializerBuilder()
.WithNamingConvention(HyphenatedNamingConvention.Instance)
Expand Down Expand Up @@ -91,17 +81,28 @@ public T Deserialize<T>(string content) where T : ContextRoot
{
try
{
return _deserializer.Deserialize<T>(content);
// At startup, sometimes deserialization fails and until now, I have no idea why.
// This error makes sure no context menus are generated and an error message is logged
// I have added some error logging and I found that it has probably something to do with Tag deserialization.
// For now, I just want to try a lock to make deserialization it threadsafe and check if this error keeps occuring in the future.
lock(_syncLock)
{
return _deserializer.Deserialize<T>(content);
}
}
catch (Exception e)
{
Console.WriteLine(e);
if (content is null)
{
_logger.LogError(e, "Deserializing content for type {Type} failed. Content is null", typeof(T).Name);
}
else
{
_logger.LogError(e, "Deserializing content for type {Type} failed. Content length is {Length}", typeof(T).Name, content.Length);
_logger.LogDebug("Content: {Content}", content); // This is not very nice
}

throw;
}
}

public string Serialize<T>(T actionMenuRoot) where T : ContextRoot
{
return _serializer.Serialize(actionMenuRoot, typeof(T));
}
}

This file was deleted.

This file was deleted.

Loading

0 comments on commit 533b5c1

Please sign in to comment.