【问题标题】:c# return combined exceptionc# 返回组合异常
【发布时间】:2016-02-29 20:03:09
【问题描述】:

我不太确定如何提出这个问题。我真的希望我能正确解释我的问题。

我的 Windows 服务中分布有多个自定义异常,我想将它们返回给启动流程步骤的主流程。

例如,我有静态类 PropertyMapper,它使用反射来读取电子邮件标题并将它们反映到特定属性。现在,如果出现异常,我想添加其他信息。就像 headerattribute 实际导致异常一样,但我不想丢失“实际”异常。

目前看起来是这样的:

try
{
    PropertyInfo pInfo = prop.Property;
    Type t = Nullable.GetUnderlyingType(pInfo.PropertyType) ?? pInfo.PropertyType;
    object safeValue = (headerAttribute.Value == null) ? null : Convert.ChangeType(headerAttribute.Value, t);
    pInfo.SetValue(mailDataObj, safeValue, null);
}
catch (Exception e)
{
    throw new PropertyMappingFailedException(headerAttribute.Field, headerParam);
}

我抛出异常以将其带回主进程,因此我只需执行一次“创建 logEntry-logic”。 '

try
{
    mailDataObj = PropertyMapper.MapProperties(mailItem);
    mailDataObj.MailItem = mailItem;
    controller = new DAKMailController(mailDataObj);

    controller.SetBasicData(procFile);
    controller.HandlePostProcessing();
}
catch (Exception e)
{
    controller.CreateLogEntry(e);
    moveFileToError(file);
}

现在我最初咳嗽的异常当然丢失了,因为我没有将它添加到我的自定义异常中,但是我该怎么做呢?另外,我的思维方式是对的还是我必须以其他方式处理异常?

我已经用 google 搜索了一下,但找不到有用的东西。我会很感激一些帮助。 :)

附:我提取了 CreateLogEntry 方法中的所有 InnerExceotions 并将它们放入单个字符串变量中。

【问题讨论】:

    标签: c# exception


    【解决方案1】:

    像这样将原始异常包装在 InnerException 字段中(在您的第一个代码示例的捕获中):

    throw new PropertyMappingFailedException(headerAttribute.Field, headerParam)
    { InnerException = e };
    

    【讨论】:

    • 啊,哦。是否可以将内部异常作为参数发送给构造函数(您使用的另一个重载)?
    • throw new CustomException("My message",ex) 这是你所说的语法堆栈跟踪是字符串
    • 发送给构造函数是通常的方式,但我不知道PropertyMappingFailedException。例如:stackoverflow.com/questions/4761216/…
    • 最坏的情况,在构造函数中创建自己的 PropertyMappingFailedException,并将 InnerException 作为参数。
    【解决方案2】:

    通常您不会相互添加异常,但您会在以下情况下对堆栈跟踪求和:

    throw ex,那么 stracktrace 就消失了,(重置)但是当你使用时:

    throw 那么它不会。

    此外,您总是在捕获各种异常,但您没有添加堆栈跟踪。最佳做法看起来更像这样:

    class Foo
    {
        DoSomething(int param)
        {
            try 
            {
                 if (/*Something Bad*/)
                 {  
                     //violates business logic etc... 
                     throw new FooException("Reason...");
                 }
                 //... 
                 //something that might throw an exception
            }
            catch (FooException ex)
            {
                 throw;
            }
            catch (Exception ex)
            {
                 throw new FooException("Inner Exception", ex);
            }
        }
    }
    

    所以总而言之,您需要使用Inner Exception

    有用的链接:

    Throwing Custom Exception Best Practices

    Is there a difference between “throw” and “throw ex”?

    Best Practices for Exceptions

    Throw exception but persist stack trace

    【讨论】:

    • 我在大多数情况下都是这样做的,但是反射会抛出很多不同的异常,尝试用 if 捕获它们是没有意义的,因为我必须要处理许多不同的数据类型从字符串转换为日期、整数、小整数……更不用说在 x 种不同的表达式中可能出现 x 种不同的异常。谢谢您提供的所有信息。不过,我想我现在会使用肮脏的解决方法。
    猜你喜欢
    • 1970-01-01
    • 2018-10-09
    • 2020-01-31
    • 2010-10-05
    • 1970-01-01
    • 2022-07-07
    • 1970-01-01
    • 2020-09-17
    • 1970-01-01
    相关资源
    最近更新 更多