Обработка ошибки при создании не валидного элемента с помощью Failure API
Мы уже ранее обсуждали примеры использования Failure API:
Вот еще одна немного запутанная ситуация, заставляющая нас снова вернуться к обсуждению этой темы с другого ракурса. Проблему озвучил Стефен Фауст (Stephen Faust) из компании Revolution Design, Inc.
Вопрос: Я создаю перекрытия для каждой комнаты в проекте. В некоторых случаях границы перекрытия получаются ошибочные из-за особенностей комнаты. В итоге создать перекрытия не получается. Для меня приемлемо решение, если я просто удалю или вообще не буду создавать перекрытия и не показывать пользователю диалог с ошибкой. Без обработки ошибки пользователь видит диалог с сообщением «Невозможно создать выдавливание», но можно нажать кнопку «Удалить элементы» и продолжить создание остальных перекрытий. Я думал, что можно сделать автоматическую обработку ошибки, но кажется это работает не так как я хотел. Вот часть кода моего класса, который реализует интерфейс IFailuresPreProcessor:
- IList<FailureMessageAccessor> fmas
- = failuresAccessor.GetFailureMessages();
- if( fmas.Count == 0 )
- { return FailureProcessingResult.Continue; }
- foreach( FailureMessageAccessor fma in fmas )
- { failuresAccessor.ResolveFailure( fma ); }
- return FailureProcessingResult.ProceedWithCommit;
Используя этот метод я все еще вижу диалог с ошибкой, только в этот раз предлагается «Удалить» все элементы. И в этом случае единственное что я могу сделать – это отменить создание элементов, что на самом деле еще хуже, т.к. в этом случае не будет создано ни одного перекрытия. Что я делаю не так? Что я должен сделать, для обработки диалога с ошибкой указав, что нужно удалить перекрытия, которые не являются валидными.
Ответ: Все что вам нужно, так это задать вариант решения для каждой ошибки.
Также потребуется сделать несколько дополнительных проверок чтобы избежать попытки решения ошибки, которую нельзя разрешить. Я предлагаю следующий подход к решению этой задачи:
- Проверить, что не валидные элементы (перекрытия) на самом деле можно удалить с помощью метода FailuresAccessors.IsElementsDeletionPermitted
- Возможно, для каждой ошибки, потребуется проверить, что разрешение ошибки с помощью удаления элементов возможно
- Предполагая, что разрешение ошибки возможно, разрешить ее с помощью метода FailuresAccessors.ResolveFailures
- Я также предполагаю, что перед тем как возвращать ProceedWithCommit, предварительно нужно сделать проверку с помощью метода FailuresAccessors.IsTransactionBeingCommitted
- Возвратить ProceedWithCommit
Ответ: Спасибо за советы.
Вот что у меня в итоге получилось и кажется это работает так как надо:
- if( failuresAccessor.GetTransactionName()
- == "Create Temporary Roofs" )
- {
- IList<FailureMessageAccessor> fmas
- = failuresAccessor.GetFailureMessages();
- if( fmas.Count == 0 )
- { return FailureProcessingResult.Continue; }
- foreach( FailureMessageAccessor fma in fmas )
- {
- FailureSeverity s = fma.GetSeverity();
- if( s == FailureSeverity.Warning )
- { failuresAccessor.DeleteWarning( fma ); }
- else if( s == FailureSeverity.Error )
- {
- if( failuresAccessor
- .IsElementsDeletionPermitted(
- fma.GetFailingElementIds().ToList() ) )
- {
- failuresAccessor.DeleteElements(
- fma.GetFailingElementIds().ToList() );
- }
- failuresAccessor.ResolveFailure( fma );
- }
- }
- return FailureProcessingResult.ProceedWithCommit;
- }
- else
- { return FailureProcessingResult.Continue; }
В первую очередь я отделил предупреждения от ошибок. Предупреждения могут быть удалены без каких-либо дополнительных действий. Ошибки обрабатываются и удаляются те элементы, которые непосредственно и являлись причиной возникновения ошибки.
Обсуждение: http://adn-cis.org/forum/index.php?topic=526
Опубликовано 12.02.2014