Skip to content

Commit

Permalink
Added logging to responders; Allow errors to return empty failures, u…
Browse files Browse the repository at this point in the history
…sed for saying 'skip this responder branch'; Have json serializer return an empty object when null is returned
  • Loading branch information
OoLunar committed Jul 1, 2024
1 parent 41b6e2f commit 9c1bd06
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 7 deletions.
15 changes: 12 additions & 3 deletions src/HyperSharp.Responders/ResponderCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,12 @@ public ResponderDelegate<TContext, TOutput> CompileResponders<TContext, TOutput>
IEnumerable<ResponderBuilder> rootResponders = _builders.Where(builder => builder.RequiredBy.Count == 0);
if (!rootResponders.Any())
{
_logger.LogWarning("No responders were found, returning an empty responder.");
return (context, cancellationToken) => Result.Success<TOutput>();
}

// Compile the root responders
_logger.LogInformation("Compiling {Count:N0} top-level responders.", rootResponders.Count());
List<ResponderDelegate<TContext, TOutput>> rootRespondersDelegates = [];
foreach (ResponderBuilder builder in rootResponders)
{
Expand All @@ -160,13 +162,15 @@ public ResponderDelegate<TContext, TOutput> CompileResponders<TContext, TOutput>
foreach (ResponderDelegate<TContext, TOutput> responder in rootRespondersDelegates)
{
Result<TOutput> result = responder(context, cancellationToken);
if (!result.IsSuccess || result.HasValue)
if (result.HasValue)
{
_logger.LogTrace("Returning result: {Result}", result);
return result;
}
}
return Result.Success<TOutput>();
_logger.LogTrace("None of the {Count:N0} top-level responders returned a value.", rootRespondersDelegates.Count);
return Result.Failure<TOutput>();
}
catch (Exception error)
{
Expand Down Expand Up @@ -246,10 +250,12 @@ public ValueTaskResponderDelegate<TContext, TOutput> CompileAsyncResponders<TCon
IEnumerable<ResponderBuilder> rootResponders = _builders.Where(builder => builder.RequiredBy.Count == 0);
if (!rootResponders.Any())
{
_logger.LogWarning("No responders were found, returning an empty responder.");
return (context, cancellationToken) => ValueTask.FromResult(Result.Success<TOutput>());
}

// Compile the root responders
_logger.LogInformation("Compiling {Count:N0} top-level responders.", rootResponders.Count());
List<ValueTaskResponderDelegate<TContext, TOutput>> rootRespondersDelegates = [];
foreach (ResponderBuilder builder in rootResponders)
{
Expand All @@ -263,12 +269,15 @@ public ValueTaskResponderDelegate<TContext, TOutput> CompileAsyncResponders<TCon
foreach (ValueTaskResponderDelegate<TContext, TOutput> responder in rootRespondersDelegates)
{
Result<TOutput> result = await responder(context, cancellationToken);
if (!result.IsSuccess || result.HasValue)
if (result.HasValue)
{
_logger.LogTrace("Returning result: {Result}", result);
return result;
}
}
_logger.LogTrace("None of the {Count:N0} top-level responders returned a value.", rootRespondersDelegates.Count);
return Result.Success<TOutput>();
}
catch (Exception error)
Expand Down
15 changes: 15 additions & 0 deletions src/HyperSharp.Results/Result.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,13 @@ public Result()
Status = ResultStatus.IsSuccess;
}

internal Result(ResultStatus status)
{
Value = null;
Errors = _emptyErrors;
Status = status;
}

internal Result(object? value)
{
Value = value;
Expand Down Expand Up @@ -94,6 +101,11 @@ internal Result(object? value, IEnumerable<Error> errors)
/// <param name="value">The value of the result.</param>
public static Result Success(object? value) => new(value);

/// <summary>
/// Returns a failed result with no error.
/// </summary>
public static Result Failure() => new(ResultStatus.None);

/// <summary>
/// Creates a failed result with an error.
/// </summary>
Expand Down Expand Up @@ -128,6 +140,9 @@ internal Result(object? value, IEnumerable<Error> errors)
/// <inheritdoc cref="Success(object?)"/>
public static Result<T> Success<T>(T value) => new(value);

/// <inheritdoc cref="Failure()"/>
public static Result<T> Failure<T>() => new(ResultStatus.None);

/// <inheritdoc cref="Failure(string)"/>
public static Result<T> Failure<T>(string error) => new(new Error(error));

Expand Down
4 changes: 2 additions & 2 deletions src/HyperSharp.Results/ResultStatus.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ public enum ResultStatus
/// <summary>
/// The result has failed and has no value.
/// </summary>
None = 0 << 0,
None = 0,

/// <summary>
/// The result has succeeded.
Expand All @@ -21,6 +21,6 @@ public enum ResultStatus
/// <summary>
/// The result does not contain a value.
/// </summary>
HasValue = 1 << 1,
HasValue = 1 << 1
}
}
7 changes: 7 additions & 0 deletions src/HyperSharp.Results/Result`1.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ public Result()
Status = ResultStatus.IsSuccess;
}

internal Result(ResultStatus status)
{
Value = default;
Errors = Result._emptyErrors;
Status = status;
}

internal Result(T? value)
{
Value = value;
Expand Down
2 changes: 1 addition & 1 deletion src/HyperSharp/HyperConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ public HyperConfiguration(IServiceCollection serviceDescriptors, HyperConfigurat
{
ArgumentNullException.ThrowIfNull(serviceDescriptors, nameof(serviceDescriptors));
ArgumentNullException.ThrowIfNull(builder, nameof(builder));
IServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();

IServiceProvider serviceProvider = serviceDescriptors.BuildServiceProvider();
if (!Uri.TryCreate($"http://{builder.ListeningEndpoint}/", UriKind.Absolute, out Uri? host))
{
throw new ArgumentException("The listening endpoint is invalid.", nameof(builder));
Expand Down
2 changes: 1 addition & 1 deletion src/HyperSharp/Protocol/HyperSerializers/JsonAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static ValueTask<bool> JsonAsync(HyperContext context, HyperStatus status

// Write Content-Type header and beginning of Content-Length header
context.Connection.StreamWriter.Write<byte>(_contentTypeJsonEncodingHeader);
byte[] body = JsonSerializer.SerializeToUtf8Bytes(status.Body, context.Connection.Server.Configuration.JsonSerializerOptions);
byte[] body = JsonSerializer.SerializeToUtf8Bytes(status.Body ?? new object(), context.Connection.Server.Configuration.JsonSerializerOptions);

// Finish the Content-Length header
context.Connection.StreamWriter.Write<byte>(Encoding.ASCII.GetBytes(body.Length.ToString()));
Expand Down

0 comments on commit 9c1bd06

Please sign in to comment.