Example #1
0
        protected virtual Exception HandleError(ClientActionContext context, Exception error, SessionMetadata session)
        {
            ErrorHandlingResult handlingResult = ErrorHandling.Handle(context, error);

            switch (handlingResult)
            {
            case ErrorHandlingResult.Close:
                session.ChangeState(context.Proxy, ProxyState.Closed);
                break;

            case ErrorHandlingResult.Recover:
                session.ClearSession();
                session.ChangeState(context.Proxy, ProxyState.Ready);
                if (!Recoverable)
                {
                    session.ChangeState(context.Proxy, ProxyState.Closed);
                }
                break;

            case ErrorHandlingResult.Rethrow:
                break;

            default:
                throw new ArgumentOutOfRangeException($"The value of '{handlingResult}' is not supported", nameof(handlingResult));
            }

            return(error);
        }
        public override async Task InvokeAsync(ClientActionContext context)
        {
            try
            {
                await Next(context).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                ErrorHandlingResult result = _errorHandling.Handle(context, e);
                if (result == ErrorHandlingResult.Close || result == ErrorHandlingResult.Recover)
                {
                    (context.Proxy as IPipelineCallback)?.ChangeState(ProxyState.Closed);
                }

                throw;
            }
        }
        public override async Task InvokeAsync(ClientActionContext context)
        {
            int tries = 0;

            while (true)
            {
                try
                {
                    await Next(context).ConfigureAwait(false);

                    (context.Proxy as IPipelineCallback)?.ChangeState(ProxyState.Open);
                    return;
                }
                catch (Exception e)
                {
                    ErrorHandlingResult errorHandlingResult = ErrorHandling.Handle(context, e);
                    switch (errorHandlingResult)
                    {
                    case ErrorHandlingResult.Close:
                        (context.Proxy as IPipelineCallback)?.ChangeState(ProxyState.Closed);
                        throw;

                    case ErrorHandlingResult.Recover:
                        if (tries >= Retries)
                        {
                            (context.Proxy as IPipelineCallback)?.ChangeState(ProxyState.Closed);
                            throw;
                        }
                        tries++;
                        break;

                    case ErrorHandlingResult.Rethrow:
                        (context.Proxy as IPipelineCallback)?.ChangeState(ProxyState.Open);
                        throw;

                    default:
                        throw new ArgumentOutOfRangeException($"The value of '{errorHandlingResult}' is not supported.", nameof(errorHandlingResult));
                    }
                }

                context.ServerConnection = null;
                await Task.Delay(RetryDelay, context.RequestAborted).ConfigureAwait(false);
            }
        }
            public async Task Execute_ThrowsError_Handle(bool recoverableProxy, ErrorHandlingResult handlingResult)
            {
                var pipeline = CreatePipeline(
                    (next, ctxt) =>
                {
                    ctxt.ServerConnection = ConnectionDescriptor;

                    if (ctxt.Action != ContractDescriptor.InitSession)
                    {
                        throw new InvalidOperationException();
                    }

                    return(next(ctxt));
                });
                var session = pipeline.Find <SessionMiddleware>();

                session.Recoverable = recoverableProxy;

                SetupSessionHandler("test session", true);
                SessionErrorHandling.Setup(r => r.Handle(It.IsAny <ClientActionContext>(), It.IsAny <Exception>())).Returns(
                    () =>
                {
                    return(handlingResult);
                });

                var proxy = CreateProxy(pipeline);
                await proxy.OpenSession("param");

                await Assert.ThrowsAsync <InvalidOperationException>(proxy.ExecuteAsync);

                if (recoverableProxy)
                {
                    switch (handlingResult)
                    {
                    case ErrorHandlingResult.Close:
                        Assert.Equal(ProxyState.Closed, proxy.State);
                        break;

                    case ErrorHandlingResult.Recover:
                        Assert.Equal(ProxyState.Ready, proxy.State);
                        break;

                    case ErrorHandlingResult.Rethrow:
                        Assert.Equal(ProxyState.Open, proxy.State);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(nameof(handlingResult), handlingResult, null);
                    }
                }
                else
                {
                    switch (handlingResult)
                    {
                    case ErrorHandlingResult.Close:
                        Assert.Equal(ProxyState.Closed, proxy.State);
                        break;

                    case ErrorHandlingResult.Recover:
                        Assert.Equal(ProxyState.Closed, proxy.State);
                        break;

                    case ErrorHandlingResult.Rethrow:
                        Assert.Equal(ProxyState.Open, proxy.State);
                        break;

                    default:
                        throw new ArgumentOutOfRangeException(nameof(handlingResult), handlingResult, null);
                    }
                }
            }
Example #5
0
        public async Task Error_EnsureProperProxyState(bool retry, ErrorHandlingResult result)
        {
            var pipeline = CreatePipeline(retry ? 1 : 0);
            var proxy = CreateProxy(pipeline);
            bool called = false;

            Callback.Setup(c => c.Handle(It.IsAny<ClientActionContext>())).Callback<ClientActionContext>(
                c =>
                    {
                        if (called)
                        {
                            if (result == ErrorHandlingResult.Rethrow)
                            {
                                throw new InvalidOperationException("This method sould not be called again.");
                            }

                            return;
                        }

                        called = true;
                        throw new InvalidOperationException();
                    }).Verifiable();

            ErrorHandling.Setup(e => e.Handle(It.IsAny<ClientActionContext>(), It.IsAny<Exception>())).Returns(result);

            if (result != ErrorHandlingResult.Recover)
            {
                await Assert.ThrowsAsync<InvalidOperationException>(() => proxy.ExecuteAsync());
            }
            else
            {
                if (retry)
                {
                    await proxy.ExecuteAsync();
                }
                else
                {
                    await Assert.ThrowsAsync<InvalidOperationException>(() => proxy.ExecuteAsync());
                }
            }

            switch (result)
            {
                case ErrorHandlingResult.Close:
                    Assert.Equal(ProxyState.Closed, proxy.State);
                    break;
                case ErrorHandlingResult.Recover:
                    if (retry)
                    {
                        Assert.Equal(ProxyState.Open, proxy.State);
                    }
                    else
                    {
                        Assert.Equal(ProxyState.Ready, proxy.State);
                    }
                    break;
                case ErrorHandlingResult.Rethrow:
                    Assert.Equal(ProxyState.Open, proxy.State);
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(result), result, null);
            }
        }
        public async Task Error_EnsureProperProxyState(bool retry, ErrorHandlingResult result)
        {
            var  pipeline = CreatePipeline(retry ? 1 : 0);
            var  proxy    = CreateProxy(pipeline);
            bool called   = false;

            Callback.Setup(c => c.Handle(It.IsAny <ClientActionContext>())).Callback <ClientActionContext>(
                c =>
            {
                if (called)
                {
                    if (result == ErrorHandlingResult.Rethrow)
                    {
                        throw new InvalidOperationException("This method sould not be called again.");
                    }

                    return;
                }

                called = true;
                throw new InvalidOperationException();
            }).Verifiable();

            ErrorHandling.Setup(e => e.Handle(It.IsAny <ClientActionContext>(), It.IsAny <Exception>())).Returns(result);

            if (result != ErrorHandlingResult.Recover)
            {
                await Assert.ThrowsAsync <InvalidOperationException>(() => proxy.ExecuteAsync());
            }
            else
            {
                if (retry)
                {
                    await proxy.ExecuteAsync();
                }
                else
                {
                    await Assert.ThrowsAsync <InvalidOperationException>(() => proxy.ExecuteAsync());
                }
            }

            switch (result)
            {
            case ErrorHandlingResult.Close:
                Assert.Equal(ProxyState.Closed, proxy.State);
                break;

            case ErrorHandlingResult.Recover:
                if (retry)
                {
                    Assert.Equal(ProxyState.Open, proxy.State);
                }
                else
                {
                    Assert.Equal(ProxyState.Closed, proxy.State);
                }
                break;

            case ErrorHandlingResult.Rethrow:
                Assert.Equal(ProxyState.Open, proxy.State);
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(result), result, null);
            }
        }
            public async Task Execute_ThrowsError_Handle(bool recoverableProxy, ErrorHandlingResult  handlingResult)
            {
                IPipeline<ClientActionContext> pipeline = CreatePipeline(
                      (next, ctxt) =>
                      {
                          ctxt.ServerConnection = ConnectionDescriptor;

                          if (ctxt.Action != ContractDescriptor.InitSession)
                          {
                              throw new InvalidOperationException();
                          }

                          return next(ctxt);
                      });
                var session = pipeline.Find<SessionMiddleware>();
                session.Recoverable = recoverableProxy;

                SetupSessionHandler("test session", true);
                SessionErrorHandling.Setup(r => r.Handle(It.IsAny<ClientActionContext>(), It.IsAny<Exception>())).Returns(
                    () =>
                        {
                            return handlingResult;
                        });

                var proxy = CreateProxy(pipeline);
                await proxy.OpenSession("param");
                await Assert.ThrowsAsync<InvalidOperationException>(proxy.ExecuteAsync);

                if (recoverableProxy)
                {
                    switch (handlingResult)
                    {
                        case ErrorHandlingResult.Close:
                            Assert.Equal(ProxyState.Closed, proxy.State);
                            break;
                        case ErrorHandlingResult.Recover:
                            Assert.Equal(ProxyState.Ready, proxy.State);
                            break;
                        case ErrorHandlingResult.Rethrow:
                            Assert.Equal(ProxyState.Open, proxy.State);
                            break;
                        default:
                            throw new ArgumentOutOfRangeException(nameof(handlingResult), handlingResult, null);
                    }
                }
                else
                {
                    switch (handlingResult)
                    {
                        case ErrorHandlingResult.Close:
                            Assert.Equal(ProxyState.Closed, proxy.State);
                            break;
                        case ErrorHandlingResult.Recover:
                            Assert.Equal(ProxyState.Closed, proxy.State);
                            break;
                        case ErrorHandlingResult.Rethrow:
                            Assert.Equal(ProxyState.Open, proxy.State);
                            break;
                        default:
                            throw new ArgumentOutOfRangeException(nameof(handlingResult), handlingResult, null);
                    }
                }
            }