ADN Open CIS
Сообщество программистов Autodesk в СНГ

12/02/2014

Обработка ошибки при создании не валидного элемента с помощью Failure API

Мы уже ранее обсуждали примеры использования Failure API:

Вот еще одна немного запутанная ситуация, заставляющая нас снова вернуться к обсуждению этой темы с другого ракурса. Проблему озвучил Стефен Фауст (Stephen Faust) из компании Revolution Design, Inc.

Вопрос: Я создаю перекрытия для каждой комнаты в проекте. В некоторых случаях границы перекрытия получаются ошибочные из-за особенностей комнаты. В итоге создать перекрытия не получается. Для меня приемлемо решение, если я просто удалю или вообще не буду создавать перекрытия и не показывать пользователю диалог с ошибкой. Без обработки ошибки пользователь видит диалог с сообщением «Невозможно создать выдавливание», но можно нажать кнопку «Удалить элементы» и продолжить создание остальных перекрытий. Я думал, что можно сделать автоматическую обработку ошибки, но кажется это работает не так как я хотел. Вот часть кода моего класса, который реализует интерфейс IFailuresPreProcessor:

Код - C#: [Выделить]
  1.   IList<FailureMessageAccessor> fmas
  2.     = failuresAccessor.GetFailureMessages();
  3.  
  4.   if( fmas.Count == 0 )
  5.   { return FailureProcessingResult.Continue; }
  6.  
  7.   foreach( FailureMessageAccessor fma in fmas )
  8.   { failuresAccessor.ResolveFailure( fma ); }
  9.  
  10.   return FailureProcessingResult.ProceedWithCommit;

Используя этот метод я все еще вижу диалог с ошибкой, только в этот раз предлагается «Удалить» все элементы. И в этом случае единственное что я могу сделать – это отменить создание элементов, что на самом деле еще хуже, т.к. в этом случае не будет создано ни одного перекрытия. Что я делаю не так? Что я должен сделать, для обработки диалога с ошибкой указав, что нужно удалить перекрытия, которые не являются валидными.

Ответ: Все что вам нужно, так это задать вариант решения для каждой ошибки.

Также потребуется сделать несколько дополнительных проверок чтобы избежать попытки решения ошибки, которую нельзя разрешить. Я предлагаю следующий подход к решению этой задачи:

  • Проверить, что не валидные элементы (перекрытия) на самом деле можно удалить с помощью метода FailuresAccessors.IsElementsDeletionPermitted
  • Возможно, для каждой ошибки, потребуется проверить, что разрешение ошибки с помощью удаления элементов возможно
  • Предполагая, что разрешение ошибки возможно, разрешить ее с помощью метода FailuresAccessors.ResolveFailures
  • Я также предполагаю, что перед тем как возвращать ProceedWithCommit, предварительно нужно сделать проверку с помощью метода FailuresAccessors.IsTransactionBeingCommitted
  • Возвратить ProceedWithCommit

Ответ: Спасибо за советы.

Вот что у меня в итоге получилось и кажется это работает так как надо:

Код - C#: [Выделить]
  1.   if( failuresAccessor.GetTransactionName()
  2.     == "Create Temporary Roofs" )
  3.   {
  4.     IList<FailureMessageAccessor> fmas
  5.       = failuresAccessor.GetFailureMessages();
  6.  
  7.     if( fmas.Count == 0 )
  8.     { return FailureProcessingResult.Continue; }
  9.  
  10.     foreach( FailureMessageAccessor fma in fmas )
  11.     {
  12.       FailureSeverity s = fma.GetSeverity();
  13.       if( s == FailureSeverity.Warning )
  14.       { failuresAccessor.DeleteWarning( fma ); }
  15.       else if( s == FailureSeverity.Error )
  16.       {
  17.         if( failuresAccessor
  18.           .IsElementsDeletionPermitted(
  19.             fma.GetFailingElementIds().ToList() ) )
  20.         {
  21.           failuresAccessor.DeleteElements(
  22.             fma.GetFailingElementIds().ToList() );
  23.         }
  24.         failuresAccessor.ResolveFailure( fma );
  25.       }
  26.     }
  27.     return FailureProcessingResult.ProceedWithCommit;
  28.   }
  29.   else
  30.   { return FailureProcessingResult.Continue; }

В первую очередь я отделил предупреждения от ошибок. Предупреждения могут быть удалены без каких-либо дополнительных действий. Ошибки обрабатываются и удаляются те элементы, которые непосредственно и являлись причиной возникновения ошибки.

 

Источник: http://thebuildingcoder.typepad.com/blog/2014/02/skip-invalid-element-generation-using-failure-api.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=526

Опубликовано 12.02.2014