如何在解析中实现异常处理?

时间:2010-09-14 11:16:56

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

我正在创建一个解析应用程序,它解析~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上做得很好(布局就会发生 要在时间内改变,我需要实现exceptionHandling和 日志记录。我需要尽可能地解析,并且必须记录错误。我知道有两种方法可以处理它:

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; 
}

优点:易于实施

缺点:如果我获得值为5的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
}

 ...

}
}

优点:解析所有可以解析的内容;

缺点:太多的copypaste(记住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
}

这是一个很好的解决方案,还是我正在重塑一个方形轮?

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

我认为XP术语中的防御性编码将是您的“解决方案”。

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

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

  • 您只需加载 DOM 并遍历感兴趣的节点(UIElement)并仅解析非null元素。

请参阅Microsoft的Best practices for Exception Handling

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

希望这有帮助,

谢谢,

维杰