Skip to content

Commit

Permalink
fix(CA1711)!: rename OnException to OnError and ExceptionContext to E…
Browse files Browse the repository at this point in the history
…rrorContext.
  • Loading branch information
skwasjer committed Dec 17, 2024
1 parent 8a65181 commit db402c3
Show file tree
Hide file tree
Showing 10 changed files with 89 additions and 83 deletions.
2 changes: 2 additions & 0 deletions Migration.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
### Migration from v5.x to 6.0.0

- `CorrelateOptions.RequestHeaders` no longer has a default value of `X-Correlation-ID`. However, if this property is set to `null` (or not configured explicitly at all), internally the behavior remains unchanged and `X-Correlation-ID` is assumed. See [#128](https://github.com/skwasjer/Correlate/issues/128).
- `OnException` is renamed to `OnError`.
- `ExceptionContext` is renamed to `ErrorContext`.

### Migration from v4.x to 5.0.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
namespace Correlate;

/// <summary>
/// Represents a context that provides access to the exception that occurred inside a correlated activity, with the ability to mark the exception as handled.
/// Represents a context that provides access to the exception that occurred inside a correlated activity, with the ability to mark the error as handled.
/// </summary>
public class ExceptionContext
public class ErrorContext
{
internal ExceptionContext(CorrelationContext correlationContext, Exception exception)
internal ErrorContext(CorrelationContext correlationContext, Exception exception)
{
CorrelationContext = correlationContext;
Exception = exception;
Expand All @@ -25,21 +25,21 @@ internal ExceptionContext(CorrelationContext correlationContext, Exception excep
public Exception Exception { get; }

/// <summary>
/// Gets or sets whether the exception is considered handled.
/// Gets or sets whether the error is considered handled.
/// </summary>
public bool IsExceptionHandled { get; set; }
public bool IsErrorHandled { get; set; }
}

/// <summary>
/// Represents a context that provides access to the exception that occurred inside a correlated activity, with the ability to mark the exception as handled and provide a return value.
/// Represents a context that provides access to the exception that occurred inside a correlated activity, with the ability to mark the error as handled and provide a return value.
/// </summary>
public class ExceptionContext<T> : ExceptionContext
public class ErrorContext<T> : ErrorContext
{
// ReSharper disable once RedundantDefaultMemberInitializer
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private T _result = default!;

internal ExceptionContext(CorrelationContext correlationContext, Exception exception)
internal ErrorContext(CorrelationContext correlationContext, Exception exception)
: base(correlationContext, exception)
{
}
Expand All @@ -53,7 +53,7 @@ public T Result
get => _result;
set
{
IsExceptionHandled = true;
IsErrorHandled = true;
_result = value!;
}
}
Expand Down
8 changes: 4 additions & 4 deletions src/Correlate.Abstractions/IAsyncCorrelationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@ public interface IAsyncCorrelationManager
/// </summary>
/// <param name="correlationId">The correlation id to use, or null to generate a new one.</param>
/// <param name="correlatedTask">The task to execute.</param>
/// <param name="onException">A delegate to handle the exception inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the exception handled, or <see langword="false" /> to throw.</param>
/// <param name="onError">A delegate to handle the error inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the error handled, or <see langword="false" /> to throw.</param>
/// <returns>An awaitable that completes once the <paramref name="correlatedTask" /> has executed and the correlation context has disposed.</returns>
/// <remarks>
/// When logging and tracing are both disabled, no correlation context is created and the task simply executed as it normally would.
/// </remarks>
Task CorrelateAsync(string? correlationId, Func<Task> correlatedTask, OnException? onException);
public Task CorrelateAsync(string? correlationId, Func<Task> correlatedTask, OnError? onError);

/// <summary>
/// Executes the <paramref name="correlatedTask" /> with its own <see cref="CorrelationContext" />.
/// </summary>
/// <typeparam name="T">The return type of the awaitable task.</typeparam>
/// <param name="correlationId">The correlation id to use, or null to generate a new one.</param>
/// <param name="correlatedTask">The task to execute.</param>
/// <param name="onException">A delegate to handle the exception inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the exception handled, or <see langword="false" /> to throw.</param>
/// <param name="onError">A delegate to handle the error inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the error handled, or <see langword="false" /> to throw.</param>
/// <returns>An awaitable that completes with a result <typeparamref name="T" /> once the <paramref name="correlatedTask" /> has executed and the correlation context has disposed.</returns>
/// <remarks>
/// When logging and tracing are both disabled, no correlation context is created and the task simply executed as it normally would.
/// </remarks>
Task<T> CorrelateAsync<T>(string? correlationId, Func<Task<T>> correlatedTask, OnException<T>? onException);
public Task<T> CorrelateAsync<T>(string? correlationId, Func<Task<T>> correlatedTask, OnError<T>? onError);
}
8 changes: 4 additions & 4 deletions src/Correlate.Abstractions/ICorrelationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,22 @@ public interface ICorrelationManager
/// </summary>
/// <param name="correlationId">The correlation id to use, or null to generate a new one.</param>
/// <param name="correlatedAction">The action to execute.</param>
/// <param name="onException">A delegate to handle the exception inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the exception handled, or <see langword="false" /> to throw.</param>
/// <param name="onError">A delegate to handle the error inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the error handled, or <see langword="false" /> to throw.</param>
/// <remarks>
/// When logging and tracing are both disabled, no correlation context is created and the action simply executed as it normally would.
/// </remarks>
void Correlate(string? correlationId, Action correlatedAction, OnException? onException);
public void Correlate(string? correlationId, Action correlatedAction, OnError? onError);

/// <summary>
/// Executes the <paramref name="correlatedFunc" /> with its own <see cref="CorrelationContext" />.
/// </summary>
/// <typeparam name="T">The return type.</typeparam>
/// <param name="correlationId">The correlation id to use, or null to generate a new one.</param>
/// <param name="correlatedFunc">The func to execute.</param>
/// <param name="onException">A delegate to handle the exception inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the exception handled, or <see langword="false" /> to throw.</param>
/// <param name="onError">A delegate to handle the error inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the error handled, or <see langword="false" /> to throw.</param>
/// <returns>Returns the result of the <paramref name="correlatedFunc" />.</returns>
/// <remarks>
/// When logging and tracing are both disabled, no correlation context is created and the action simply executed as it normally would.
/// </remarks>
T Correlate<T>(string? correlationId, Func<T> correlatedFunc, OnException<T>? onException);
public T Correlate<T>(string? correlationId, Func<T> correlatedFunc, OnError<T>? onError);
}
15 changes: 15 additions & 0 deletions src/Correlate.Abstractions/OnError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Correlate;

/// <summary>
/// A delegate for handling errors inside correlation scope.
/// </summary>
/// <param name="errorContext">The error context.</param>
#pragma warning disable CA1711
public delegate void OnError(ErrorContext errorContext);

/// <summary>
/// A delegate for handling errors inside correlation scope.
/// </summary>
/// <param name="errorContext">The error context.</param>
public delegate void OnError<T>(ErrorContext<T> errorContext);
#pragma warning restore CA1711
13 changes: 0 additions & 13 deletions src/Correlate.Abstractions/OnException.cs

This file was deleted.

54 changes: 29 additions & 25 deletions src/Correlate.Core/CorrelationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class CorrelationManager : IAsyncCorrelationManager, ICorrelationManager,
private readonly ICorrelationIdFactory _correlationIdFactory;
private readonly DiagnosticListener? _diagnosticListener;
private readonly ILogger _logger;
private readonly CorrelationManagerOptions _options = new CorrelationManagerOptions();
private readonly CorrelationManagerOptions _options = new();

/// <summary>
/// Initializes a new instance of the <see cref="CorrelationManager" /> class.
Expand Down Expand Up @@ -93,12 +93,12 @@ public IActivity CreateActivity()
/// </summary>
/// <param name="correlationId">The correlation id to use, or null to generate a new one.</param>
/// <param name="correlatedTask">The task to execute.</param>
/// <param name="onException">A delegate to handle the exception inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the exception handled, or <see langword="false" /> to throw.</param>
/// <param name="onError">A delegate to handle the error inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the error handled, or <see langword="false" /> to throw.</param>
/// <returns>An awaitable that completes once the <paramref name="correlatedTask" /> has executed and the correlation context has disposed.</returns>
/// <remarks>
/// When logging and tracing are both disabled, no correlation context is created and the task simply executed as it normally would.
/// </remarks>
public Task CorrelateAsync(string? correlationId, Func<Task> correlatedTask, OnException? onException)
public Task CorrelateAsync(string? correlationId, Func<Task> correlatedTask, OnError? onError)
{
if (correlatedTask is null)
{
Expand All @@ -112,7 +112,7 @@ public Task CorrelateAsync(string? correlationId, Func<Task> correlatedTask, OnE
await correlatedTask().ConfigureAwait(false);
return Void.Null;
},
onException
onError
);
}

Expand All @@ -122,12 +122,12 @@ public Task CorrelateAsync(string? correlationId, Func<Task> correlatedTask, OnE
/// <typeparam name="T">The return type of the awaitable task.</typeparam>
/// <param name="correlationId">The correlation id to use, or null to generate a new one.</param>
/// <param name="correlatedTask">The task to execute.</param>
/// <param name="onException">A delegate to handle the exception inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the exception handled, or <see langword="false" /> to throw.</param>
/// <param name="onError">A delegate to handle the error inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the error handled, or <see langword="false" /> to throw.</param>
/// <returns>An awaitable that completes with a result <typeparamref name="T" /> once the <paramref name="correlatedTask" /> has executed and the correlation context has disposed.</returns>
/// <remarks>
/// When logging and tracing are both disabled, no correlation context is created and the task simply executed as it normally would.
/// </remarks>
public Task<T> CorrelateAsync<T>(string? correlationId, Func<Task<T>> correlatedTask, OnException<T>? onException)
public Task<T> CorrelateAsync<T>(string? correlationId, Func<Task<T>> correlatedTask, OnError<T>? onError)
{
if (correlatedTask is null)
{
Expand All @@ -137,7 +137,9 @@ public Task<T> CorrelateAsync<T>(string? correlationId, Func<Task<T>> correlated
return ExecuteAsync(
correlationId,
correlatedTask,
onException is null ? null : context => onException((ExceptionContext<T>)context)
onError is null
? null
: context => onError((ErrorContext<T>)context)
);
}

Expand All @@ -146,11 +148,11 @@ public Task<T> CorrelateAsync<T>(string? correlationId, Func<Task<T>> correlated
/// </summary>
/// <param name="correlationId">The correlation id to use, or null to generate a new one.</param>
/// <param name="correlatedAction">The action to execute.</param>
/// <param name="onException">A delegate to handle the exception inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the exception handled, or <see langword="false" /> to throw.</param>
/// <param name="onError">A delegate to handle the error inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the error handled, or <see langword="false" /> to throw.</param>
/// <remarks>
/// When logging and tracing are both disabled, no correlation context is created and the action simply executed as it normally would.
/// </remarks>
public void Correlate(string? correlationId, Action correlatedAction, OnException? onException)
public void Correlate(string? correlationId, Action correlatedAction, OnError? onError)
{
if (correlatedAction is null)
{
Expand All @@ -163,7 +165,7 @@ public void Correlate(string? correlationId, Action correlatedAction, OnExceptio
correlatedAction();
return Void.Null;
},
onException);
onError);
}

/// <summary>
Expand All @@ -172,12 +174,12 @@ public void Correlate(string? correlationId, Action correlatedAction, OnExceptio
/// <typeparam name="T">The return type.</typeparam>
/// <param name="correlationId">The correlation id to use, or null to generate a new one.</param>
/// <param name="correlatedFunc">The func to execute.</param>
/// <param name="onException">A delegate to handle the exception inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the exception handled, or <see langword="false" /> to throw.</param>
/// <param name="onError">A delegate to handle the error inside the correlation scope, before it is disposed. Returns <see langword="true" /> to consider the error handled, or <see langword="false" /> to throw.</param>
/// <returns>Returns the result of the <paramref name="correlatedFunc" />.</returns>
/// <remarks>
/// When logging and tracing are both disabled, no correlation context is created and the action simply executed as it normally would.
/// </remarks>
public T Correlate<T>(string? correlationId, Func<T> correlatedFunc, OnException<T>? onException)
public T Correlate<T>(string? correlationId, Func<T> correlatedFunc, OnError<T>? onError)
{
if (correlatedFunc is null)
{
Expand All @@ -187,11 +189,13 @@ public T Correlate<T>(string? correlationId, Func<T> correlatedFunc, OnException
return Execute(
correlationId,
correlatedFunc,
onException is null ? null : context => onException((ExceptionContext<T>)context)
onError is null
? null
: context => onError((ErrorContext<T>)context)
);
}

private async Task<T> ExecuteAsync<T>(string? correlationId, Func<Task<T>> correlatedTask, OnException? onException)
private async Task<T> ExecuteAsync<T>(string? correlationId, Func<Task<T>> correlatedTask, OnError? onError)
{
IActivity activity = CreateActivity();
CorrelationContext correlationContext = StartActivity(correlationId, activity);
Expand All @@ -200,7 +204,7 @@ private async Task<T> ExecuteAsync<T>(string? correlationId, Func<Task<T>> corre
{
return await correlatedTask().ConfigureAwait(false);
}
catch (Exception ex) when (HandlesException(onException, correlationContext, ex, out T exceptionResult))
catch (Exception ex) when (HandlesException(onError, correlationContext, ex, out T exceptionResult))
{
return exceptionResult;
}
Expand All @@ -210,7 +214,7 @@ private async Task<T> ExecuteAsync<T>(string? correlationId, Func<Task<T>> corre
}
}

private T Execute<T>(string? correlationId, Func<T> correlatedFunc, OnException? onException)
private T Execute<T>(string? correlationId, Func<T> correlatedFunc, OnError? onError)
{
IActivity activity = CreateActivity();
CorrelationContext correlationContext = StartActivity(correlationId, activity);
Expand All @@ -219,7 +223,7 @@ private T Execute<T>(string? correlationId, Func<T> correlatedFunc, OnException?
{
return correlatedFunc();
}
catch (Exception ex) when (HandlesException(onException, correlationContext, ex, out T exceptionResult))
catch (Exception ex) when (HandlesException(onError, correlationContext, ex, out T exceptionResult))
{
return exceptionResult;
}
Expand All @@ -229,28 +233,28 @@ private T Execute<T>(string? correlationId, Func<T> correlatedFunc, OnException?
}
}

private static bool HandlesException<T>(OnException? onException, CorrelationContext correlationContext, Exception ex, out T result)
private static bool HandlesException<T>(OnError? onError, CorrelationContext correlationContext, Exception ex, out T result)
{
if (!ex.Data.Contains(CorrelateConstants.CorrelationIdKey))
{
// Because we're about to lose context scope, enrich exception with correlation id for reference by calling code.
ex.Data.Add(CorrelateConstants.CorrelationIdKey, correlationContext.CorrelationId);
}

if (onException is not null)
if (onError is not null)
{
bool hasResultValue = typeof(T) != typeof(Void);

// Allow caller to handle exception inline before losing context scope.
ExceptionContext exceptionContext = hasResultValue
? new ExceptionContext<T>(correlationContext, ex)
: new ExceptionContext(correlationContext, ex);
ErrorContext errorContext = hasResultValue
? new ErrorContext<T>(correlationContext, ex)
: new ErrorContext(correlationContext, ex);

onException(exceptionContext);
if (exceptionContext.IsExceptionHandled)
onError(errorContext);
if (errorContext.IsErrorHandled)
{
result = hasResultValue
? ((ExceptionContext<T>)exceptionContext).Result
? ((ErrorContext<T>)errorContext).Result
: default!;
return true;
}
Expand Down
Loading

0 comments on commit db402c3

Please sign in to comment.