Browse Source

Handle remote service error response in dynamic HTTP Proxy clients wherever possible. #90.

pull/113/head
Halil İbrahim Kalkan 9 years ago
parent
commit
b74260645b
  1. 5
      src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs
  2. 28
      src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpRemoteCallException.cs
  3. 23
      src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs
  4. 2
      test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/IRegularTestController.cs
  5. 8
      test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestController.cs
  6. 8
      test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs

5
src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ExceptionHandling/AbpExceptionFilter.cs

@ -1,8 +1,10 @@
using System.Net; using System.Collections.Generic;
using System.Net;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Primitives;
using Volo.Abp.Authorization; using Volo.Abp.Authorization;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities;
@ -47,6 +49,7 @@ namespace Volo.Abp.AspNetCore.Mvc.ExceptionHandling
} }
context.HttpContext.Response.StatusCode = GetStatusCode(context); context.HttpContext.Response.StatusCode = GetStatusCode(context);
context.HttpContext.Response.Headers.Add(new KeyValuePair<string, StringValues>("_AbpErrorFormat", "true"));
context.Result = new ObjectResult( context.Result = new ObjectResult(
new RemoteServiceErrorResponse( new RemoteServiceErrorResponse(

28
src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/AbpRemoteCallException.cs

@ -0,0 +1,28 @@
using System;
using System.Runtime.Serialization;
namespace Volo.Abp.Http.Client
{
[Serializable]
public class AbpRemoteCallException : AbpException
{
public RemoteServiceErrorInfo Error { get; set; }
public AbpRemoteCallException()
{
}
public AbpRemoteCallException(SerializationInfo serializationInfo, StreamingContext context)
: base(serializationInfo, context)
{
}
public AbpRemoteCallException(RemoteServiceErrorInfo error)
: base(error.Message)
{
Error = error;
}
}
}

23
src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/DynamicHttpProxyInterceptor.cs

@ -94,12 +94,12 @@ namespace Volo.Abp.Http.Client.DynamicProxying
}; };
AddHeaders(invocation, action, requestMessage); AddHeaders(invocation, action, requestMessage);
var response = await client.SendAsync(requestMessage); var response = await client.SendAsync(requestMessage);
if (!response.IsSuccessStatusCode) if (!response.IsSuccessStatusCode)
{ {
throw new AbpException($"Remote service returns error! HttpStatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}"); await ThrowExceptionForResponseAsync(response);
} }
return await response.Content.ReadAsStringAsync(); return await response.Content.ReadAsStringAsync();
@ -123,9 +123,24 @@ namespace Volo.Abp.Http.Client.DynamicProxying
var clientConfig = _clientOptions.HttpClientProxies.GetOrDefault(typeof(TService)) var clientConfig = _clientOptions.HttpClientProxies.GetOrDefault(typeof(TService))
?? throw new AbpException($"Could not get DynamicHttpClientProxyConfig for {typeof(TService).FullName}."); ?? throw new AbpException($"Could not get DynamicHttpClientProxyConfig for {typeof(TService).FullName}.");
return _remoteServiceOptions.RemoteServices.GetOrDefault(clientConfig.RemoteServiceName) return _remoteServiceOptions.RemoteServices.GetOrDefault(clientConfig.RemoteServiceName)
?? _remoteServiceOptions.RemoteServices.Default ?? _remoteServiceOptions.RemoteServices.Default
?? throw new AbpException($"Could not get DynamicHttpClientProxyConfig for {typeof(TService).FullName}."); ?? throw new AbpException($"Could not get DynamicHttpClientProxyConfig for {typeof(TService).FullName}.");
} }
private async Task ThrowExceptionForResponseAsync(HttpResponseMessage response)
{
if (response.Headers.Contains("_AbpErrorFormat"))
{
var errorResponse = _jsonSerializer.Deserialize<RemoteServiceErrorResponse>(
await response.Content.ReadAsStringAsync()
);
throw new AbpRemoteCallException(errorResponse.Error);
}
throw new AbpException($"Remote service returns error! HttpStatusCode: {response.StatusCode}, ReasonPhrase: {response.ReasonPhrase}");
}
} }
} }

2
test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/IRegularTestController.cs

@ -7,5 +7,7 @@ namespace Volo.Abp.Http.DynamicProxying
int IncrementValue(int value); int IncrementValue(int value);
Task<int> IncrementValueAsync(int value); Task<int> IncrementValueAsync(int value);
Task GetException1Async();
} }
} }

8
test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestController.cs

@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Volo.Abp.Application.Services; using Volo.Abp.Application.Services;
using Volo.Abp.AspNetCore.Mvc; using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Ui;
namespace Volo.Abp.Http.DynamicProxying namespace Volo.Abp.Http.DynamicProxying
{ {
@ -23,5 +24,12 @@ namespace Volo.Abp.Http.DynamicProxying
{ {
return Task.FromResult(value + 1); return Task.FromResult(value + 1);
} }
[HttpGet]
[Route("get-exception1")]
public Task GetException1Async()
{
throw new UserFriendlyException("This is an error message!");
}
} }
} }

8
test/Volo.Abp.Http.Client.Tests/Volo/Abp/Http/DynamicProxying/RegularTestControllerClientProxy_Tests.cs

@ -1,6 +1,7 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Shouldly; using Shouldly;
using Volo.Abp.Http.Client;
using Xunit; using Xunit;
namespace Volo.Abp.Http.DynamicProxying namespace Volo.Abp.Http.DynamicProxying
@ -27,5 +28,12 @@ namespace Volo.Abp.Http.DynamicProxying
{ {
(await _controller.IncrementValueAsync(42)).ShouldBe(43); (await _controller.IncrementValueAsync(42)).ShouldBe(43);
} }
[Fact]
public async Task GetException1Async()
{
var exception = await Assert.ThrowsAsync<AbpRemoteCallException>(async () => await _controller.GetException1Async());
exception.Error.Message.ShouldBe("This is an error message!");
}
} }
} }
Loading…
Cancel
Save