【问题标题】:C# Exception: Does it have an unique value/identifierC# 异常:它是否具有唯一值/标识符
【发布时间】:2014-04-17 12:15:09
【问题描述】:

Exception 类是否有唯一的 Id 或任何其他唯一的修饰符(GUID、...)?

我正在后端服务中记录生成的异常。但我的目标是只记录每个异常一次。

也许这里有一个有用的例子: 该服务有 3 层:

DAL (SQL-Interaction)
        => Exception A occurs here and is being logged into the database

BL (BusinessLayer)
         => Exception A is passed to here but isn't being logged
         => Exception B is thrown here and is being logged into the table

Services (Service Interface)
         => Exception A is passed to here but isn't being logged
         => Exception B is passed to here but isn't being logged
...
Client-solutions

我目前的解决方案(我个人非常不喜欢):

我编写了一个自己的异常(继承自基类异常)。当第一次抛出任何异常时,它会被记录下来。然后将其转换为我自己的例外并重新抛出。我自己的异常类型的异常没有记录在数据库中

示例(这是伪代码)

DAL - Layer
     try{}
     catch (Exception e)
     {
          // log in database
          // log in logfile
          // Cast to OwnException
          // rethrown as OwnException
     }

BL - Layer
     try{}
     catch (OwnException e)
     {
          // log in logfile
          // rethrow e
     }
     catch (Exception e)
     {
          // log in database
          // log in logfile
          // Cast to OwnException
          // rethrow as OwnException
     }

更新:我真正在寻找的是一个 Id/unique 修饰符。我会扫描数据库中是否存在此 ID。如果这个 id 不存在,那么我会写一条记录。如果它存在,那么它只会被重新抛出。

【问题讨论】:

  • 你为什么要在不同的地方多次登录?这有什么用?
  • 如果 BL 层内发生异常,则需要记录它。如果它发生在 DAL 层内,那么我必须被记录。但是必须让客户端解决方案知道发生了异常。所以我向客户的方向重新抛出异常,这样他们就知道出了什么可怕的问题。我可以在顶层记录它,是的,但显然这里的最佳做法是登录每个方法。

标签: c# exception exception-handling


【解决方案1】:

您可以创建 Exception 并创建一个新的属性布尔值作为 "Logged" ,当您记录异常时将 true 设置为 "Logged" 并且在记录之前的其他层中您需要验证是否未记录。

public class YourException : ApplicationException
    {
        public YourException () { }

        public YourException (string message) : base(message) { }

        public YourException (string message, Exception innerException) : base(message, innerException) { }

        public bool LoggedInLogFile { get; set; }

        public bool LoggedInDataBase { get; set; }
    }

在您的 DAL 中:

 try{}
 catch (Exception e)
 {
      // log in database
      // log in logfile
      var ex = new YourException (e.Message);
      ex.LoggedInLogFile  = true;
      ex.LoggedInDataBase = true;
      throw ex;
 }

在您的服务层中:

 try{}
     catch (YourException e)
     {
          if(!e.LoggedInLogFile)
              //Log in file
          if(!e.LoggedInDataBase)
              //Log in Database
     }

【讨论】:

  • 所以我会使用我的'OwnException'并提供他们的属性'Logged'?当异常到达我的日志记录逻辑时,我会测试属性“Logged”是否需要写入数据库?
【解决方案2】:

我不会创建自己的自定义异常。我要做的是明确捕获我知道可能在 DAL 中发生的异常,例如 SQLException。在 BL 中捕获可能在那里发生的特定异常,并让其余的向上传播。

您的 BL 和 DAL 不太可能需要记录相同的异常,将它们分开以便它们各自捕获它们负责的集合,然后重新抛出它们以便客户端 UI 可以捕获它们。

编辑

忘了说,请确保你在重新抛出时使用:

throw,

而不是:

throw ex;

所以你不会丢失你的堆栈跟踪

【讨论】:

  • 你说得很好。在这个应用程序中,在 BS-lvl 上发生 SQLException 是完全不可能的。
  • 我会这样做。
猜你喜欢
  • 2021-03-03
  • 1970-01-01
  • 1970-01-01
  • 2018-03-01
  • 2012-04-17
  • 2011-08-25
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多