【发布时间】:2020-12-26 19:24:01
【问题描述】:
我最近尝试为我的 Web API 设置日志系统。我决定要创建自定义的异常类,这些类可以被我的 GlobalExceptionHandler 抛出然后记录下来。但是,我在访问自定义异常对象的 StackTrace 时遇到了一些问题。
我设置了一个名为 LoggableException 的自定义异常类,我将它用作我想要记录到我的数据库的所有自定义异常的父类。
public class LoggableException : Exception
{
public LogEntity Log { get; set; }
public string ResponseMessage { get; set; }
public LoggableException(LogEntity _log, string _responseMessage) : base(_log.ExceptionMessage)
{
Log = _log;
Log.Level = LogLevel.Warn;
Log.Exception = GetType().Name;
Log.StackTrace = StackTrace.Substring(0, 1000);
ResponseMessage = _responseMessage;
}
}
这是我的一个自定义 LoggableExceptions 的示例:
public class InvalidPassword : LoggableException
{
public InvalidPassword(string email) : base(new LogEntity()
{
ExceptionMessage = $"Invalid password. email: {email}",
ResponseCode = (int) HttpStatusCode.Unauthorized
}, $"Unknown email or incorrect password.")
{ }
}
但是,似乎每当我抛出这些 LoggableExceptions 之一时,<System.NullReferenceException: Object reference not set to an instance of an object. 也会被抛出 Log.StackTrace = StackTrace.Substring(0, 1000);。我这样做是为了不在我的数据库中存储巨大的 StackTrace 字符串,但 StackTrace 始终为空。我假设如果我调用基本构造函数它会自动实例化 StackTrace,但我想我错了。谁能向我解释我在这里做错了什么?我对 C# 还是比较陌生。
【问题讨论】:
-
仅使用自定义异常类型进行日志记录是有问题的;实际上登录该异常的构造函数是致命的缺陷(正如您所发现的)。堆栈跟踪不可用,因为在构造时,甚至还没有抛出异常——堆栈展开以查找处理程序仅在该点完成。异常处理程序应该执行任何所需的日志记录,而不是异常本身。对于专门的日志记录,只需在调用站点直接使用记录器(如果需要,可以借助
StackTrace类),不要让异常执行。 -
好的,这完全有道理。感谢您的帮助!
标签: c# asp.net exception stack-trace