public async Task Invoke(HttpContext context, IHostEnvironment webHostEnvironment)
    {
        // Using the Request-Id header, one can find the log for server-related exceptions
        context.Response.Headers.Add("Request-ID", context.TraceIdentifier);

        try
        {
            await _next(context);
        }
        catch (Exception e)
        {
            var exception        = UnWrapException(e);
            var isKnownException = exception is KnownException;
            var statusCode       = (int)(exception is RestException restExp ? restExp.StatusCode : HttpStatusCode.InternalServerError);

            RestExceptionPayload restExceptionPayload = new RestExceptionPayload
            {
                // The details of all of the exceptions are returned only in dev mode. in any other modes like production, only the details of the known exceptions are returned.
                Message       = isKnownException || webHostEnvironment.IsDevelopment() ? exception.Message : nameof(UnknownException),
                ExceptionType = isKnownException ? exception.GetType().FullName : typeof(UnknownException).FullName
            };

            if (exception is ResourceValidationException validationException)
            {
                restExceptionPayload.Details = validationException.Details;
            }

            context.Response.StatusCode = statusCode;
            await context.Response.WriteAsJsonAsync(restExceptionPayload);
        }
    }
示例#2
0
    protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.Headers.Authorization is null && RuntimeInformation.ProcessArchitecture != Architecture.Wasm)
        {
            var access_token = await _tokenProvider.GetAcccessToken();

            if (access_token is not null)
            {
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", access_token);
            }
        }

        var response = await base.SendAsync(request, cancellationToken);

        if (!response.IsSuccessStatusCode && response.Content.Headers.ContentType?.MediaType == "application/json")
        {
            if (response.Headers.TryGetValues("Request-ID", out IEnumerable <string>?values) && values is not null && values.Any())
            {
                RestExceptionPayload restError = await response.Content.ReadFromJsonAsync(TodoTemplateJsonContext.Default.RestExceptionPayload);

                Type exceptionType = typeof(RestExceptionPayload).Assembly.GetType(restError.ExceptionType) ?? typeof(UnknownException);

                Exception exp = (Exception)Activator.CreateInstance(exceptionType, args: new object[] { restError.Message });

                if (exp is ResourceValidationException resValidationException)
                {
                    resValidationException.Details = restError.Details;
                }

                throw exp;
            }
        }

        response.EnsureSuccessStatusCode();

        return(response);
    }