Как реализовать обработку исключений при разборе? - PullRequest
3 голосов
/ 14 сентября 2010

Я создаю приложение для синтаксического анализа, которое анализирует ~ 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 (разметки бывают изменить во времени), мне нужно реализовать протоколирование. Мне нужно разобрать как можно больше, и ошибки должны быть зарегистрированы. Я знаю 2 способа справиться с этим:

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

Плюсы: Простота реализации

Минусы: если я получу exc на значении 5, у меня нет шансов проанализировать значение 6,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 и регистрирует другие. Так что теперь я должен написать это:

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 ]

2 голосов
/ 14 сентября 2010

Используйте опцию SafeCall, поскольку она работает, ее легко прочитать, и вы всегда можете изменить реализацию SafeCall, если хотите изменить механизм ведения журнала.

1 голос
/ 14 сентября 2010

Я бы сказал, что защитное кодирование в терминах XP было бы «решением» в вашем случае.

  • Это проверяет UIElement! = Null перед анализом любых значений из исключенного элемента пользовательского интерфейса. Потому что пользователь склонен менять разметку HTML. (Я испытал это в моем приложении очистки экрана)

  • Таким образом, вам не нужно использовать несколько блоков try catch для разбора различных значений.

  • Вы можете просто загрузить DOM и пройти по заинтересованному узлу (UIElement) и проанализировать только ненулевые элементы.

См. Рекомендации по обработке исключений от Microsoft.

Я полагаю, что вы просто хотите пропустить узлы, которые не были найдены, из разбора.

Надеюсь, это поможет,

Спасибо

Виджей

...