【问题标题】:How to implement Exception Handling in Parsing?解析中如何实现异常处理?
【发布时间】:2011-04-12 02:54:56
【问题描述】:

我正在创建一个解析应用程序,它可以解析约 20 个站点,每个站点约 7-15 个值。伪代码如下:

ParserA : ParserBase 
{
public override SomeEntity Parse(...)
{
 SomeEntity se = new SomeEntity();

 //some code, parsing value1;
 //some code, parsing value1;
 //some code, parsing value1;

 //some code, parsing value2;
 //some code, parsing value2;
 //some code, parsing value2;

 //some code, parsing value3;
 //some code, parsing value3;
 //some code, parsing value3;

 //some code, parsing value4;
 //some code, parsing value4;
 //some code, parsing value4;

 ...

 return se; 
}
}

ParserB : ParserBase {...} 
ParserC : ParserBase {...} 
...

等等

只要解析器从来没有很好地处理 html(布局发生 期间更改),我需要实现异常处理和 记录。我需要尽可能多地解析,并且必须记录错误。我知道两种处理方法:

public override SomeEntity Parse(...)
{
 SomeEntity se = new SomeEntity();

try {
 //some code, parsing value1;
 //some code, parsing value1;
 //some code, parsing value1;

 //some code, parsing value2;
 //some code, parsing value2;
 //some code, parsing value2;

 //some code, parsing value3;
 //some code, parsing value3;
 //some code, parsing value3;

 //some code, parsing value4;
 //some code, parsing value4;
 //some code, parsing value4;

 ...
}
catch (Exception e)
{
 //Log
}
 return se; 
}

优点:易于实施

缺点:如果我在 value5 处得到 exc,我就没有机会解析 value6、7 等。

2)

ParserA : ParserBase 
{
public override SomeEntity Parse(...)
{
try
{
 //some code, parsing value1;
 //some code, parsing value1;
 //some code, parsing value1;
}
catch(Exception e)
{
 // Log
}

try
{
 //some code, parsing value2;
 //some code, parsing value2;
 //some code, parsing value2;
catch(Exception e)
{
 // Log
}

try
{
 //some code, parsing value3;
 //some code, parsing value3;
 //some code, parsing value3;
catch(Exception e)
{
 // Log
}

try
{
 //some code, parsing value4;
 //some code, parsing value4;
 //some code, parsing value4;
catch(Exception e)
{
 // Log
}

 ...

}
}

优点:所有可以解析的东西都会被解析;

缺点:复制粘贴过多(记住 20 个解析器,每个解析器 7-15 个值。

我想少写多做,所以我实现了 Safecall 函数,它接受委托并在 try-catch 块中执行它,并记录 ot。所以现在我必须写这个:

SafeCall( () => { 
 //some code, parsing value4;
 //some code, parsing value4;
 //some code, parsing value4;
});

而不是这个:

try
{
 //some code, parsing value4;
 //some code, parsing value4;
 //some code, parsing value4;
catch(Exception e)
{
 // Log
}

这是一个好的解决方案还是我正在重新发明一个方轮?

【问题讨论】:

  • 解析单个值的代码是什么?感觉不同的值之间会有共性,我会坚持错误处理和登录。
  • @Grzenio,值的解析逻辑不同。
  • 看来你的解析方法做得太多了。如果每个部分都有错误处理很重要,为什么不将逻辑拆分成更细粒度的方法,包含它们自己的异常处理/日志记录?
  • 你能把解析逻辑封装成实现相同接口的类吗?

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


【解决方案1】:

我会说 XP 术语中的防御性编码将是您的“最佳”解决方案。

  • 这是在解析来自预期 UI 元素的任何值之前检查 UIElement != null。因为用户倾向于更改 HTML 标记。 (我在我的屏幕抓取应用程序中遇到过这种情况)

  • 这样您就不必使用多个 try catch 块来解析不同的值。

  • 您可以简单地加载DOM并沿着感兴趣的节点(UIElement)遍历并仅解析非空元素。

请参考微软的Best practices for Exception Handling

我认为您只是想从解析中跳过未找到的节点。

希望这会有所帮助,

谢谢,

维杰

【讨论】:

  • 是的,我想跳过无法解析的节点(有点)。我不想使用空检查,因为通常我必须检查以下内容:XpathQuery Result、Regex Result、Collection Length,有时 - 所有这些都在一起。
【解决方案2】:

使用 SafeCall 选项,因为它工作正常,易于阅读,如果您想更改日志记录机制,您可以随时更改 SafeCall 实现。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-20
    • 2010-11-19
    • 2011-06-06
    • 1970-01-01
    相关资源
    最近更新 更多