包含返回值错误的设计模式

时间:2015-10-26 19:33:00

标签: c# design-patterns exception-handling error-logging

我正在通过其API编写另一个软件的加载项。 API返回的类只能通过本机软件和API进行访问。所以我正在编写自己独立的POCO / DTO对象,这些对象映射到API类。我正在研究一个将在原生文件中读取的功能,并返回这些POCO对象的集合,我可以偷到其他地方。目前我正在使用JSON.NET将这些类序列化为JSON,如果这很重要的话。

例如,我可能有像这样的DTO

public class MyPersonDTO
{
    public string Name {get; set;}
    public string Age {get; set;}
    public string Address {get; set;}       
}

..和这样的方法将本地“人物”读入我的DTO对象

public static class MyDocReader
{
    public static IList<MyPersonDTO> GetPersons(NativeDocument doc)
    {
        //Code to read Persons from doc and return MyPersonDTOs
    }
}

我使用测试文件设置了单元测试,但是在其他文件上运行导出时遇到了意外问题。有时原生对象会有意想不到的值,或者API中存在缺陷,当没有理由时会抛出异常。

目前,当发生“异常”事件时,我只记录异常,导出失败。但我已经决定我宁愿导出我能做的事情,并在某处记录错误。

最简单的选择是只记录并吞下异常并返回我能做的事情,然而我的调用代码无法知道何时出现问题。

我正在考虑的一个选项是将错误字典作为单独的输出参数返回。密钥将标识无法读取的属性,该值将包含异常/错误的详细信息。

public static class MyDocReader
{
    public static IList<MyPersonDTO> persons GetPersons(NativeDocument doc, out IDictionary<string, string> errors)
    {
        //Code to read persons from doc
    }
}

或者我也在考虑将错误存储在返回对象本身中。这会使我的对象的大小膨胀,但还有一个额外的好处就是直接将错误存储在我的对象中。因此,如果某人的导出产生错误,我不必担心在他们的计算机上追踪正确的日志文件。

public class MyPersonDTO
{
    public string Name {get; set;}
    public string Age {get; set;}
    public string Address {get; set;}

    public IDictionary<string, string> Errors {get; set;}   
}

这通常如何处理?是否有其他选项可以报告错误以及我没有考虑的返回值?

2 个答案:

答案 0 :(得分:4)

您可以将结果包装在回复或响应消息中,而不是将错误作为实体的一部分返回。然后,错误可能是响应消息的一部分,而不是实体。

这样做的好处是实体 clean

缺点是将错误映射回有问题的实体/属性会更加困难。

当发送批次的实体时,这种下行可能是一个大问题。当API更加面向单一实体时,它就不那么重要了。

答案 1 :(得分:1)

原则上,如果API出现问题(无法恢复),则调用代码必须知道发生了异常。因此,它可以采取适当的策略来处理它。

因此,我想到的方法受到同样的哲学的影响 -

1&GT;定义自己的例外让我们说IncompleteReadException。 此异常应具有属性IList<MyPersonDTO>,以存储在异常发生之前读取的记录。

public class IncompleteReadException : Exception
{
    IList<MyPersonDTO> RecordsRead { get; private set; }       

   public IncompleteReadException(string message, IList<MyPersonDTO> recordsRead, Exception innerException) : base(message,innerException)
    {
        this.RecordsRead = recordsRead;
    }
}

2 - ;当读取时发生异常时,您可以捕获原始异常,将原始异常包装在此异常中。抛出IncompleteReadException

这将允许调用代码(应用程序代码)制定策略来处理读取不完整数据时的情况。