【问题标题】:Custom Exception handing with Property class in C#在 C# 中使用 Property 类进行自定义异常处理
【发布时间】:2020-07-10 10:36:26
【问题描述】:

我知道这已经被问过了。我需要开发用户定义的异常处理以及属性类,但我没有检索新添加的属性(DSMException.cs 属性)异常。我经历了这两个解决方案-

Custom exception with properties

What is the correct way to make a custom .NET Exception serializable?

我有一个Property 类-DSMException,其中包含三个属性Type、Message、InnerExceptionMessage,需要显示。

DSMException.cs

 public class DSMException
    {
        public string Type { get; set; }
        public string Message { get; set; }
        public string InnerExceptionMessage { get; set; }
    }

给出了相应的自定义异常类。

FatalException.cs

 public class FatalException :Exception
    {
        DSMException exception = new DSMException();
        public FatalException():base()
        {

        }

        public FatalException(string? Message): base(Message)
        {
            exception.Type = "FATAL";
            exception.Message = "MESSAGE:" + Message;
        }

        public FatalException(string? Message,Exception ex) : base(Message,ex)
        {
            exception.Type = "FATAL";
            exception.Message = "MESSAGE: " + ex.Message;
            exception.InnerExceptionMessage = "MORE DET: " + ex.ToInnerMostException().Message;
        }
    }

我正在抛出如下代码的异常 Channel.cs

 public override void Run(ServiceSettings settings, DataSource dataSource, string path)
 {
 try
{
  var channel = entities.Channels
         .Where(c => c.Name == parameters.Channel)
         .FirstOrDefault();
    if (channel != null)
      {
        // ANY LOGIC
      }
   else
    {
      throw new FatalException("Invalid Channel Name !!!");
    }
}
 catch (FatalException ex)// for channel is null
 {
     throw ex;
 }
catch (Exception ex)
 {
    throw ex;
 }
}

在捕获 Exceptions-FatalExceptions 期间此处引发错误

FolderInvocation.cs(错误)

 private void DoFolderInvocation(DataSource dataSource, Plugin plugin)
{
  // Do type invocation
try
 {
 result = helper.Invoke(importableFile.Path);// This invokes the Run method, I skipped those codes

 if (result == null)
     logger.WriteError($"{dataSource.Key}: Unknown error while processing file '{importableFile.Path}'.");
else if (result.Success == false)
      logger.WriteError($"{dataSource.Key}: Error while processing file '{importableFile.Path}'. 
      {result.Message}");
 else
     logger.WriteDebug($"{dataSource.Key}: File '{importableFile.Path}' was processed successfully. 
     {result.Message}");
 }
 catch (FatalException exFatal)// **Problem Arises here-> need to get Ex.Type in the FatalException**
 {
   logger.WriteError($"{dataSource.Key}: An error occurred while processing data source: 
   {exFatal.Message}");
    throw exFatal;
 }
 catch (Exception ex)
{
 logger.WriteError($"{dataSource.Key}: Invocation error while processing file '{importableFile.Path}'. 
 {ex.Message}");
}
}

我所缺少的,就这些最小复制代码而言是正确的,但我需要在 FatalException 中获取 Ex.Type。请给我建议。

【问题讨论】:

  • 这里出现什么问题?能否请您添加错误文本?
  • 您的DSMException exception 是私人的。不能在FatalException的实例之外访问,它是字段,不是属性。

标签: c# .net


【解决方案1】:

如果我理解正确,您只需将字段作为公共属性转发:

public class FatalException: Exception
{
    private readonly DSMException _exception = new DSMException();

    /* ... snip ... */

    public string MyType => _exception.Type;
    public string MyMessage => _exception.Message;
    public string MyInnerExceptionMessage => _exception.InnerExceptionMessage;
}

然而,它似乎确实有点违背了DSMException 类的目的。您可以DSMException 设为公共属性,但我强烈建议事先将其设为不可变。

我显然不知道 DSMException 类的预期用途,但是由于无论如何所有值都在构造函数中组装,您也可以直接分配给公共属性:

public FatalException(string? Message): base(Message)
{
    Type = "FATAL";
    Message = "MESSAGE:" + Message;
}

public string MyType { get ; }
public string MyMessage { get ; }
public string MyInnerExceptionMessage { get ; }

继续不变性建议:您可以像这样定义DSMException 类:

public sealed class DSMException
{
    public DSMException(string type, string message, string innerMessage)
    {
        Type = type;
        Message = message;
        InnerExceptionMessage = innerMessage;
    }

    public string Type { get; }
    public string Message { get; }
    public string InnerExceptionMessage { get; }
}

...然后将其设为公共财产:

public class FatalException: Exception
{
    /* ... snip ... */

    public DSMException DSM => _exception;
}

看来您仍然需要在FatalExceptionErrorExceptionWarningException 等之间复制大部分构造函数代码。

还要注意,只要您的自定义异常只在同一个 AppDomain 中飞来飞去,一切都很好;当它们可能跨越域边界(例如通过电汇)时,DSMException 需要可序列化,并且您的自定义异常的序列化方法也需要实现。

【讨论】:

  • 用户定义的异常还有四种,分别是FatalException、InfoException、WarningException、ErrorException。我创建了 DSMExceptions.cs 以减少代码处理这四种类型的异常。
  • 您介意编辑我的代码吗?因为在初始化 FatalExceptions.cs 的一部分时出现了一些错误。
  • 如果它的代码按预期工作就不是什么大问题了。 :)) 您能否添加一些有关您所观察到的错误的详细信息(针对您的问题)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 2019-07-15
  • 2020-05-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多