Skip to content

Commit

Permalink
Exception handling refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
NikolayPianikov committed Jun 6, 2024
1 parent 8d302b1 commit 736c9ad
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 59 deletions.
79 changes: 79 additions & 0 deletions src/Pure.DI.Core/Core/ExceptionHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
namespace Pure.DI.Core;

internal class ExceptionHandler(ILogger<ExceptionHandler> logger)
: IExceptionHandler
{
public void SafeRun<T>(T state, Action<T> action)
{
try
{
action(state);
}
catch (AggregateException aggregateException)
{
OnAggregateException(aggregateException);
}
catch (CompileErrorException compileException)
{
OnCompileException(compileException);
}
catch (HandledException handledException)
{
OnHandledException(handledException);
}
catch (OperationCanceledException)
{
throw;
}
catch (Exception exception)
{
OnException(exception);
}
}

private void OnAggregateException(AggregateException aggregateException)
{
foreach (var exception in aggregateException.InnerExceptions)
{
switch (exception)
{
case CompileErrorException compileError:
OnCompileException(compileError);
break;

case HandledException handledException:
OnHandledException(handledException);
break;

default:
OnException(exception);
break;
}
}
}

private void OnCompileException(CompileErrorException exception) =>
logger.CompileError(exception.ErrorMessage, exception.Location, exception.Id);

private void OnHandledException(HandledException handledException) =>
logger.Log(
new LogEntry(
#if DEBUG
DiagnosticSeverity.Info,
#else
DiagnosticSeverity.Hidden,
#endif
"Code generation aborted.",
default,
LogId.InfoGenerationInterrupted,
handledException));

private void OnException(Exception exception) =>
logger.Log(
new LogEntry(
DiagnosticSeverity.Error,
"An unhandled error has occurred.",
default,
LogId.ErrorUnhandled,
exception));
}
71 changes: 14 additions & 57 deletions src/Pure.DI.Core/Core/Generator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Pure.DI.Core;
internal sealed class Generator(
IGlobalOptions globalOptions,
IProfiler profiler,
ILogger<Generator> logger,
IExceptionHandler exceptionHandler,
IObserversRegistry observersRegistry,
IObserver<LogEntry> logObserver,
IBuilder<IEnumerable<SyntaxUpdate>, IEnumerable<MdSetup>> metadataBuilder,
Expand All @@ -21,67 +21,24 @@ public Unit Build(IEnumerable<SyntaxUpdate> updates)
using var logObserverToken= observersRegistry.Register(logObserver);
try
{
foreach (var setup in metadataBuilder.Build(updates))
{
try
{
codeBuilderFactory().Build(setup);
}
catch (CompileErrorException compileException)
{
OnCompileException(compileException);
}
catch (HandledException handledException)
{
OnHandledException(handledException);
}
}
}
catch (OperationCanceledException)
{
}
catch (CompileErrorException compileException)
{
OnCompileException(compileException);
}
catch (HandledException handledException)
{
OnHandledException(handledException);
}
catch (Exception exception)
{
OnException(exception);
exceptionHandler.SafeRun(updates, ProcessUpdates);
}
finally
{
logObserver.OnCompleted();
}

return Unit.Shared;
}

private void OnCompileException(CompileErrorException exception) =>
logger.CompileError(exception.ErrorMessage, exception.Location, exception.Id);

private void OnHandledException(Exception handledException) =>
logger.Log(
new LogEntry(
#if DEBUG
DiagnosticSeverity.Info,
#else
DiagnosticSeverity.Hidden,
#endif
"Code generation aborted.",
default,
LogId.InfoGenerationInterrupted,
handledException));

private void OnException(Exception exception) =>
logger.Log(
new LogEntry(
DiagnosticSeverity.Error,
"An unhandled error has occurred.",
default,
LogId.ErrorUnhandled,
exception));

private void ProcessUpdates(IEnumerable<SyntaxUpdate> updates)
{
foreach (var setup in metadataBuilder.Build(updates))
{
exceptionHandler.SafeRun(setup, BuildCode);
}
}

private void BuildCode(MdSetup setup) =>
codeBuilderFactory().Build(setup);
}
6 changes: 6 additions & 0 deletions src/Pure.DI.Core/Core/IExceptionHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Pure.DI.Core;

internal interface IExceptionHandler
{
void SafeRun<T>(T state, Action<T> action);
}
4 changes: 2 additions & 2 deletions src/Pure.DI.Core/Core/MetadataSyntaxWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public void Visit(IMetadataVisitor metadataVisitor, in SyntaxUpdate update)
visitors.Reverse();
#if DEBUG
visitors.ForEach(i => ProcessInvocation(i));
#else
Parallel.ForEach(visitors, i => ProcessInvocation(i));
#else
Parallel.ForEach(visitors, new ParallelOptions() { CancellationToken = cancellationToken }, i => ProcessInvocation(i));
#endif
foreach (var visitor in visitors)
{
Expand Down
1 change: 1 addition & 0 deletions src/Pure.DI.Core/Generator.Composition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ private void Setup() => DI.Setup(nameof(Generator))
.Bind().To<Formatter>()
.Bind().To<NodeInfo>()
.Bind<IEqualityComparer<INamedTypeSymbol>>().To<NamedTypeSymbolEqualityComparer>()
.Bind().To<ExceptionHandler>()

// Validators
.Bind(Tag.Type).To<MetadataValidator>()
Expand Down

0 comments on commit 736c9ad

Please sign in to comment.