Exception treatment not working

Asked

Viewed 224 times

0

Hello, I am studying C# and I was trying to do exception treatment using middleware, to send the message and the exception code to the client, but it is not working very well.

Debugging, breakpoint is passing normally in middleware, but is not sending the error to the client. The middleware code is this:

app.UseExceptionHandler(errorApp =>
        {
            errorApp.Run(async context =>
            {
                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                context.Response.ContentType = "application/json";

                var error = context.Features.Get<IExceptionHandlerFeature>();

                if (error != null)
                {
                    var ex = error.Error;

                    await context.Response.WriteAsync(new ErrorDto()
                    {
                        StatusCode = context.Response.StatusCode,
                        Message = ex.Message
                    }.ToString(), Encoding.UTF8);
                }
            });
        });

public class ErrorDto
{
    public int StatusCode { get; set; }

    public string Message { get; set; }

    public override string ToString()
    {
        return JsonConvert.SerializeObject(this);
    }
}

and my Startup.Cs is like this:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
            app.UseCors("Desenvolvimento");
        else
            app.UseHsts();

        app.UseDefaultFiles();
        app.UseStaticFiles();
        app.UseHttpsRedirection();
        app.ExceptionHandler();

        app.UseMvc(opts =>
        {
            opts.MapRoute(
                name: "default",
                template: "api/{controller}/{action}/{id?}");
        });
    }
  • Would not be app.UseExceptionHandler()?

2 answers

0

To create an Exception Middleware, I’m using this treatment here

Create a middleware class

     public class ErrorHandlingMiddleware
        {
            private readonly RequestDelegate next;

            public ErrorHandlingMiddleware(RequestDelegate next)
            {
                this.next = next;
            }

// nesse Invoke eh possivel injetar qualquer coisa
            public async Task Invoke(HttpContext context)
            {
                try
                {
                    await next(context);
                }
                catch (Exception ex)
                {
//Capture o erro aqui
                    await HandleExceptionAsync(context, ex);
                }
            }

//Trate o erro aqui
            private static Task HandleExceptionAsync(HttpContext context, Exception exception)
            {
                var code = HttpStatusCode.InternalServerError; // 500 if unexpected
                var result = string.Empty; // coloque qualquer coisa aqui

                context.Response.ContentType = "application/json";
                context.Response.StatusCode = (int)code;
                return context.Response.WriteAsync(result); // retorne o objeto como json.
            }
        }

Then add the class in your configure in Startup.Cs

//Startup.cs

public virtual void Configure(IApplicationBuilder app)
            {
               // seu codigo aqui

                app.UseMiddleware(typeof(ErrorHandlingMiddleware));

             //Antes de app.UseMvc();
                app.UseMvc();
            }

0

In Asp.net core you treat this in "Filters". Create a class that implements the "Iexceptionfilter" interface. In it you can use the context to perform any treatment, you can also normally inject what you need into the constructor. Example:

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using System.Net;

namespace Exemplo1.API.Infrastructure.Filters
{
    public class HttpGlobalExceptionFilter : IExceptionFilter
    {
        private readonly IHostingEnvironment env;
        private readonly ILogger<HttpGlobalExceptionFilter> logger;

        public HttpGlobalExceptionFilter(IHostingEnvironment env, ILogger<HttpGlobalExceptionFilter> logger)
        {
            this.env = env;
            this.logger = logger;
        }

        public void OnException(ExceptionContext context)
        {
            logger.LogError(new EventId(context.Exception.HResult),
                context.Exception,
                context.Exception.Message);

            var json = new JsonErrorResponse
            {
                Messages = new[] { "Ocorreu um erro. Tente novamente." }
            };

            if (env.IsDevelopment())
            {
                json.DeveloperMessage = context.Exception;
            }

            // Result asigned to a result object but in destiny the response is empty. This is a known bug of .net core 1.1
            // It will be fixed in .net core 1.1.2. See https://github.com/aspnet/Mvc/issues/5594 for more information
            context.Result = new InternalServerErrorObjectResult(json);
            context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError;

            context.ExceptionHandled = true;
        }

        private class JsonErrorResponse
        {
            public string[] Messages { get; set; }

            public object DeveloperMessage { get; set; }
        }

    }

    public class InternalServerErrorObjectResult : ObjectResult
    {
        public InternalServerErrorObjectResult(object error)
            : base(error)
        {
            StatusCode = StatusCodes.Status500InternalServerError;
        }
    }
}

Then just add in the startup:

services.AddMvc(options =>
        {
            options.Filters.Add(typeof(HttpGlobalExceptionFilter));
        })

To find out which filters are available and when they run in the Asp.net core pipeline, you can access the following link:

Filters in ASP.NET Core

Browser other questions tagged

You are not signed in. Login or sign up in order to post.