SAS: Как предотвратить ПРЕРЫВАНИЕ при ошибке

#error-handling #sas

#обработка ошибок #sas

Вопрос:

У меня ожидаемая ошибка с amp;syserr. of 1020 . При возникновении ошибки программа завершает работу со следующим сообщением:

 FATAL: Unrecoverable I/O error detected in the execution of the DATA step program.
       Aborted during the EXECUTION phase.
  

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

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

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

Комментарии:

1. Как вы запускаете программу? Интерактивный? Пакет?

2. Я думаю, технически интерактивный. Я нахожусь в оконной среде SAS, используя улучшенный редактор. Я выбираю инструкции, которые хочу выполнить, а затем нажимаю «Отправить». Код, который выдает ошибку, существует в макросе.

3. Когда вы говорите «прервано», вы просто имеете в виду, что этап передачи данных завершается? Или SAS завершается? Или макрос завершается неправильно?

4. Код прекращает выполнение, и управление возвращается расширенному редактору. В журнал записывается сообщение об ОШИБКЕ. В идеале я хотел бы выполнить код между возникновением ошибки и записью сообщения об ошибке. Я знаю, что в SAS нет конструкции try / catch, поэтому я надеюсь, что может существовать механизм типа «on error goto». antonis.de/qbebooks/gwbasman/onerror.html

5. После того, как это произойдет, если вы отправите еще один небольшой шаг С ДАННЫМИ, это сработает? Или вся ваша интерактивная сессия в значительной степени нарушена, и вам нужно закрыть SAS и перезапустить?

Ответ №1:

Поскольку вы знаете, что установлен параметр amp;syserr, одним из вариантов было бы написать свой собственный макрос %onError, что-то вроде:

 %macro OnError(debug=0);
  %if amp;syserr ne 0 %then %do;
    %*blah blah blah;
  %end;
%mend OnError;
  

Итак, ваш код выглядит следующим образом:

 data want;
  set have;
  oops;
run;
%OnError()
  

Обратите внимание, что amp;syserr сбрасывается после каждой границы шага, поэтому вам нужно протестировать его сразу после подозрительного шага. Существуют другие переменные макроса с кодами возврата, которые сохраняются.

Если ошибка была достаточно серьезной, чтобы SAS перешла в режим проверки синтаксиса (установите obs = 0 и noreplace), вам пришлось бы сделать больше для восстановления. Но я думаю, что по умолчанию в interactive SAS это отключено.

Комментарии:

1. Я думаю, что если бы это была обычная ошибка, это было бы совершенно правильно. Однако я думаю, что ошибка, на которую он ссылается, не следует за этими строками — это скорее ошибка в SAS code supervisor или что-то еще, где она перегружается. Хотя и не уверен.

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

3. Согласен, это не позволит избежать прерывания или сообщения об ошибке. Это может быть использовано для «восстановления» в смысле повторной попытки выполнения шага (если это была проблема с сетью или аналогичная) или запуска альтернативного шага, или отправки кому-либо электронного письма и т.д. Но это не похоже на настоящую попытку … поймать. Я думаю, что вы застряли, пытаясь либо избежать ошибки, либо восстановиться после возникновения ошибки.

Ответ №2:

Хотя это неуклюже, желаемого результата можно достичь с помощью операторов %LABEL и %GOTO.

Необходимо учитывать, что

«метка, которая является целью инструкции %GOTO, должна существовать в текущем макросе; вы не можете перейти к метке в другом макросе с помощью инструкции %GOTO».

Поскольку ошибка возникает в коде, уже содержащемся в макросе, отдельный макрос не может использоваться для обработки события ошибки. (SAS рекомендует не создавать макросы внутри других макросов).

Комментарии:

1. Хороший улов. Я не смог придумать пример, который эмулирует мою проблему, поэтому я удалил пример, на который вы ссылаетесь. Мы надеемся, что ваш ответ вместе с %goto /% label должен предоставить достаточную информацию для процветания.