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

11/06/2014

Обработка ошибок и предупреждений

Программная обработка диалогов с предупреждениями

Вопрос: Возможно ли с помощью Revit MEP 2011 API обрабатывать сообщения с предупреждениями?

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

И еще, если предупреждения могут быть перехвачены и обработаны, можно ли так же обработать сообщения об ошибках? Например, если при работе возникает ошибка, можно ли программно определить номер ошибки, выбрать подходящее действие для обработки этой ошибки и продолжить выполнение некоторых действий без фактического отображения диалога?

Ответ: Да, обработка предупреждений в том виде, как вы описали, возможна. Фактически это можно сделать тремя способами (от простого к сложному):

  • Простой: Обработать событие DialogBoxShowing
  • Более сложный, гибкий и мощный: Failure API
  • Экстремальный, не связанный с Revit API: Windows Hook

Ранее это уже обсуждали, и все три подхода можно найти по ссылке обнаружение и обработка сообщений с предупреждениями и ошибками (на англ.).  Также пример одного из способа на русском языке: Обработка ошибки при создании не валидного элемента с помощью Failure API

Ответом на второй ваш вопрос также будет «да». Подход тот же самый что и с предупреждениями и обсуждается по ссылкам выше.

Для обработки ошибок, Failure API будет все же самым подходящим вариантом.

Разрешение конфликтных ситуаций с помощью Failure API

Вопрос: В моей надстройке, при редактировании семейства Дверь с помощью Revit API возникает ошибка.

С помощью Failure API разрешить ошибку не выходит и в итоге диалог с ошибкой отображается пользователю.

Но в Revit 2014 мне все же удавалось разрешить ошибку без отображения диалога. Можете подсказать что не так в данном случае и почему диалог все же отображается?

Ответ: Вам нужно вызвать метод SetProcessingResult для аргумента события и задать значение FailureProcessingResult.ProceedWithCommit, например, вот так:

Код - C#: [Выделить]
  1.     public void DoFailureProcessing(
  2.       object sender,
  3.       FailuresProcessingEventArgs args )
  4.     {
  5.       FailuresAccessor fa = args.GetFailuresAccessor();
  6.  
  7.       // Inside event handler, get all warnings
  8.  
  9.       IList<FailureMessageAccessor> a
  10.         = fa.GetFailureMessages();
  11.  
  12.       int count = 0;
  13.  
  14.       foreach( FailureMessageAccessor failure in a )
  15.       {
  16.         TaskDialog.Show( "Failure",
  17.           failure.GetDescriptionText() );
  18.  
  19.         fa.ResolveFailure( failure );
  20.  
  21.         ++count;
  22.       }
  23.  
  24.       if( 0 < count
  25.         && args.GetProcessingResult()
  26.           == FailureProcessingResult.Continue )
  27.       {
  28.         args.SetProcessingResult(
  29.           FailureProcessingResult.ProceedWithCommit );
  30.       }
  31.     }

Пример кода в руководстве разработчика Revit API, в котором рассказывается об обработке конфликтов, этот метод не вызывается, так как там рассматривается удаление предупреждений.

Для предупреждений это работает, так как удаление предупреждения это «мгновенная» операция и результат обработки события остается неизменным (по умолчанию результат равен «Continue»).

Ошибки же не удаляются мгновенно. Фактически они удаляются только после последующей регенерации модели. Удаление ошибок может также привести к ошибке, поэтому гарантировать успешность результата нельзя. По этой причине необходимо обязательно вызвать метод SetProcessingResult и передать в качестве аргумента FailureProcessingResult.ProceedWithCommit.

Источник: http://thebuildingcoder.typepad.com/blog/2014/05/on-handling-warnings-and-failures.html

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

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