Получить информацию об исключении - PullRequest
0 голосов
/ 24 июня 2018

Я хотел бы иметь функцию, которая, когда ему дается исключение, извлекает всю информацию об этом исключении и затем записывает ее в базу данных.

Перед переходом на .NET Core 2,Я смог сделать это следующим образом:

var details = new ErrorDetails();
if (ex == null) return details;
var st = new StackTrace(ex, true);
var frames = st.GetFrames();
if (frames != null && frames.Length > 0)
{
    var errorDetails = frames.Select(frame => new ErrorDetails
    {
        FileName = frame.GetFileName(),
        LineNumber = frame.GetFileLineNumber().ToString(),
        MethodName = frame.GetMethod().Name,
        ClassName = frame.GetMethod().DeclaringType.FullName
    });

    return errorDetails.FirstOrDefault();
}
return details;

С тех пор, как мой проект переключился на .NET Core 2, этот код возвращается с большей частью этой информации, равной null / default;Я посмотрел на кадры, которые я извлекаю, и у них больше нет информации.Для таких вещей, как FileName и LineNumber, значения равны нулю.Для таких вещей, как MethodName и ClassName, это значение есть, но оно неправильное.

Я бы разбил свой проект с помощью такого кода:

public class TestController : Controller
{
    [HttpGet]
    [AllowAnonymous]
    public string ErrorHandling()
    {
        var a = int.Parse("fail parsing on purpose");
        return a.ToString();
    }
}

Значение для MethodNameв итоге получается StringToNumber и для ClassName это System.Number

Я не могу найти в Интернете никакой информации о том, почему это так и как я могу получить информацию об исключении.

РЕДАКТИРОВАТЬ:

Я подумал, что было бы также полезно перечислить, как я обрабатываю исключения.Я написал собственный обработчик исключений ошибок промежуточного программного обеспечения, очень похожий на тот, что описан в этом сообщении SO:

https://stackoverflow.com/a/48625298/2371128

РЕДАКТИРОВАТЬ 2: Это выполняется в режиме отладки.

Ответы [ 2 ]

0 голосов
/ 25 июня 2018

Вот мое предложение:

public class ExceptionDetail
{
    public string Message { get; set; }

    public string InnerExceptionMessage { get; set; }

    public string StackTrace { get; set; }

    public IEnumerable<string> StackTraceLines { get; set; }

    public string Target { get; set; }

    public string Source { get; set; }
}


var exDetail = new ExceptionDetail
{
    Message = exception.Message,
    InnerExceptionMessage = exception.InnerException?.Message,
    Source = exception.Source,
    StackTrace = exception.StackTrace,
    StackTraceLines = exception.StackTrace.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList(),
    Target = exception.TargetSite.ToString()
};
0 голосов
/ 25 июня 2018

Добавьте следующее в свой Startup.cs

app.UseExceptionHandler(
         options =>
         {
             options.Run(
             async context =>
             {
                 var ex = context.Features.Get<IExceptionHandlerFeature>();
                 if (ex != null)
                 {
                     try
                     {
                         await System.Threading.Tasks.Task.Run(async () =>
                          {
                              var builder = new DbContextOptionsBuilder<DBContext>();
                              builder.UseSqlServer(_config["ConnectionStrings:ContextConnection"]);
                              var _context = new DBContext(_config, builder.Options, httpContextAccessor);
                              //Log to DB
                              await repository.LogError(_context, ex.Error.Message, $"{ex.Error.InnerException?.Message}<br/>{ex.Error.StackTrace}");
                          });

                     }
                     finally
                     {
                         //Optional
                         await repository.SendMailToAdmin(ex.Error.Message, $"{ex.Error.InnerException?.Message}<br/>{ex.Error.StackTrace}");
                     }

                     context.Response.Redirect("/app/Errors/500");
                 }
             });
         }
        );

// ErrorLog.cs

 public class ErrorLog
{
    public int Id { get; set; }
    [Required]
    [StringLength(500)]
    public string Error { get; set; }
    [Required]
    [StringLength(4000)]
    public string Details { get; set; }

    public int? UserId { get; set; }
    public int CreatedBy { get; set; }
    public DateTime CreatedDate { get; set; }
}
...