Exception handling not working

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

Debugging, the breakpoint is normally passing through the middleware, but it 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 looks 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?}");
        });
    }
    
asked by anonymous 19.12.2018 / 22:45

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 to 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();
            }
    
27.12.2018 / 17:01
0

In ASP.NET core you treat this in "filters". Create a class that implements the "IExceptionFilter" interface. In it you can use context to perform all the treatment, you can also inject normally what you need in 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 it to 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

    
30.12.2018 / 02:00