Using latest NET5 Hosted Blazor WASM.
I am using the HttpClientInterceptor to catch errors returned from the server. All internal errors are catches and logged on the server and a error object are returned to the Blazor client.
I save the error object in local storage and then I navigate to the error page.
The problem is that calling e.GetCapturedContentAsync() somehow triggers the HttpClientInterceptor class multiple times.
Picture below is one call to the server that returns a 500 with an error object.
One of the entries holds data from the server the rest must be some kind of side effect of doing the async work.
When I am not calling e.GetCapturedContentAsync() then everthing works fine.
This is my HttpInterceptorService
public class HttpInterceptorService
{
private readonly HttpClientInterceptor _interceptor;
private readonly NavigationManager _navManager;
private readonly ILocalStorageService _localStorageService;
public HttpInterceptorService(HttpClientInterceptor interceptor, NavigationManager navManager,
ILocalStorageService localStorageService)
{
_interceptor = interceptor;
_navManager = navManager;
_localStorageService = localStorageService;
}
public void MonitorEvent() => _interceptor.AfterSendAsync += InterceptResponse;
private async Task InterceptResponse(object sender, HttpClientInterceptorEventArgs e)
{
if (e?.Response == null || e.Response.IsSuccessStatusCode) return;
await _localStorageService.RemoveItemAsync("apiError");
var responseCode = e.Response.StatusCode;
ApiError apiError;
var message = "Something went wrong, please contact Administrator";
string detail;
switch (responseCode)
{
case HttpStatusCode.NotFound:
message = "The requested resource was not found.";
detail = "The resource was not found. Please report the error if the problem persists.";
apiError = new ApiError {Title = message, Status = (short) responseCode, Detail = detail};
await _localStorageService.SetItemAsync("apiError", apiError);
_navManager.NavigateTo("/ErrorPage");
break;
case HttpStatusCode.Unauthorized:
case HttpStatusCode.Forbidden:
message = "You are not authorized to access this resource. ";
detail = "Please contact Helpdesk and the can help you get access to the resource.";
apiError = new ApiError {Title = message, Status = (short) responseCode, Detail = detail};
await _localStorageService.SetItemAsync("apiError", apiError);
_navManager.NavigateTo("/ErrorPage");
break;
case HttpStatusCode.InternalServerError:
apiError = await GetApiError500FromContent(e) ?? new ApiError();
if (string.IsNullOrEmpty(apiError.Id))
{
apiError.Status = (short) responseCode;
apiError.Title = "Internal server error";
}
await _localStorageService.SetItemAsync($"apiError_{Guid.NewGuid()}", apiError);
_navManager.NavigateTo("/ErrorPage");
break;
default:
message = "Something went wrong, please contact Administrator";
detail = "Please report the error if the problem persists.";
apiError = new ApiError {Title = message, Status = (short) responseCode, Detail = detail};
await _localStorageService.SetItemAsync($"apiError", apiError);
_navManager.NavigateTo("/ErrorPage");
break;
}
throw new HttpRequestException(message);
}
private static async Task<ApiError> GetApiError500FromContent(HttpClientInterceptorEventArgs e)
{
try
{
var capturedContent = await e.GetCapturedContentAsync();
var apiError = await capturedContent.ReadFromJsonAsync<ApiError>();
if (apiError != null && !string.IsNullOrEmpty(apiError.Id))
{
return apiError;
}
}
catch
{
}
return null;
}
public void DisposeEvent() => _interceptor.AfterSendAsync -= InterceptResponse;
}
