Skip to content

Commit

Permalink
Merge pull request #245 from astankov2/master
Browse files Browse the repository at this point in the history
Check if an exception is client-side by checking if the exception source is a registered assembly in CloneStateBehavior
  • Loading branch information
StevenTCramer authored Dec 14, 2020
2 parents 6deb263 + 0fa27b1 commit 14b30ad
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Build/BlazorStateMultiStage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pr: none
variables:
Major: 3
Minor: 4
Patch: 2
Patch: 3
DotNetSdkVersion: 3.1.404

stages:
Expand Down
4 changes: 2 additions & 2 deletions Source/BlazorState/Extensions/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public static IServiceCollection AddBlazorState
EnsureLogger(aServiceCollection);
EnsureHttpClient(aServiceCollection);
EnsureMediator(aServiceCollection, blazorStateOptions);
EnusureStates(aServiceCollection, blazorStateOptions);
EnsureStates(aServiceCollection, blazorStateOptions);

aServiceCollection.AddScoped<BlazorHostingLocation>();
aServiceCollection.AddScoped<JsonRequestHandler>();
Expand Down Expand Up @@ -145,7 +145,7 @@ private static void EnsureMediator(IServiceCollection aServiceCollection, Blazor
}
}

private static void EnusureStates(IServiceCollection aServiceCollection, BlazorStateOptions aBlazorStateOptions)
private static void EnsureStates(IServiceCollection aServiceCollection, BlazorStateOptions aBlazorStateOptions)
{
foreach (Assembly assembly in aBlazorStateOptions.Assemblies)
{
Expand Down
24 changes: 9 additions & 15 deletions Source/BlazorState/Pipeline/CloneState/CloneStateBehavior.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,27 @@ namespace BlazorState.Pipeline.State
using MediatR;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

internal class CloneStateBehavior<TRequest, TResponse> : IPipelineBehavior<TRequest, TResponse>
{
private readonly ILogger Logger;
private readonly IMediator Mediator;
private readonly BlazorStateOptions BlazorStateOptions;
private readonly IStore Store;

public CloneStateBehavior
(
(
ILogger<CloneStateBehavior<TRequest, TResponse>> aLogger,
BlazorStateOptions aBlazorStateOptions,
IStore aStore,
IMediator aMediator
)
IMediator aMediator)
{
Logger = aLogger;
Logger.LogDebug($"{GetType().Name} constructor");
BlazorStateOptions = aBlazorStateOptions;
Store = aStore;
Mediator = aMediator;
}
Expand Down Expand Up @@ -79,7 +82,7 @@ RequestHandlerDelegate<TResponse> aNext
Logger.LogWarning($"{className}: InnerError: {aException?.InnerException?.Message}");
Logger.LogWarning($"{className}: Restoring State of type: {declaringType}");

if (!IsApiCallException(aException) && originalState != null)
if (IsClientSideException(aException) && originalState != null)
{
Store.SetState(originalState as IState);

Expand All @@ -98,16 +101,7 @@ RequestHandlerDelegate<TResponse> aNext
}
}

private bool IsApiCallException(Exception aException)
{
string stackTrace = aException.ToString();

if (stackTrace.ToLowerInvariant().Contains("httprequestexception"))
{
return true;
}

return false;
}
private bool IsClientSideException(Exception aException) =>
BlazorStateOptions.Assemblies.Any(aAssembly => aAssembly.GetName().Name == aException.Source);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,17 @@ public async Task WillNotRollbackState_When_ExceptionOccursInAnEndpointOnServer(
CounterState.Initialize(aCount: 22);
Guid preActionGuid = CounterState.Guid;

var throwExceptionAction = new ThrowExceptionAction
var throwServerSideExceptionAction = new ThrowServerSideExceptionAction
{
Message = new HttpRequestException(
"Response status code does not indicate success: 500 (Internal Server Error).").ToString()
Message = "Response status code does not indicate success: 500 (Internal Server Error)."
};

// Act
Exception exception = await Shouldly.Should.ThrowAsync<Exception>(async () =>
await Send(throwExceptionAction));
await Send(throwServerSideExceptionAction));

// Assert
exception.Message.ShouldBe(throwExceptionAction.Message);
exception.Message.ShouldBe(throwServerSideExceptionAction.Message);
CounterState.Guid.Equals(preActionGuid).ShouldBeFalse();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace TestApp.Client.Features.Counter
{
using BlazorState;

public partial class CounterState
{
public class ThrowServerSideExceptionAction : IAction
{
public string Message { get; set; }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace TestApp.Client.Features.Counter
{
using BlazorState;
using MediatR;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using TestApp.Client.Features.Base;

public partial class CounterState
{
internal class ThrowServerSideExceptionHandler : BaseHandler<ThrowServerSideExceptionAction>
{
public ThrowServerSideExceptionHandler(IStore aStore) : base(aStore) { }

/// <summary>
/// Intentionally throw so we can test exception handling.
/// </summary>
/// <param name="aThrowServerSideExceptionAction"></param>
/// <param name="aCancellationToken"></param>
/// <returns></returns>
public override Task<Unit> Handle
(
ThrowServerSideExceptionAction aThrowServerSideExceptionAction,
CancellationToken aCancellationToken
) => throw new HttpRequestException(aThrowServerSideExceptionAction.Message)
{
Source = $"{nameof(TestApp)}.Server"
};
}
}
}

0 comments on commit 14b30ad

Please sign in to comment.