Capturing ANY error and processing afterwards regardless of severity

Reply
Occasional Contributor
Posts: 11

Capturing ANY error and processing afterwards regardless of severity

Hi All!

I've had a look around and failed to find anything addressing this particular issue.

I have an error checking process macro that checks for conditions and then writes info out to an error audit file. When the process is complete this file is written out to an error log which contains only datetime stamps and information relating to the error.

My problem is that when something unexpected happens I can capture it by writing the information out to the dataset but the final step to write the dataset out to the error log seems to always result in an empty log despite the dataset having content.

Can someone explain what is probably going on here and how I can work around it?

Thanks!

Brian.

Super User
Posts: 5,099

Re: Capturing ANY error and processing afterwards regardless of severity

Well, you haven't shown much of how you go about it ... here's a reasonable guess.

To end all further processing, you probably generate a statement like endsas; or %abort;

You might be generating that statement just a little too early, before writing to the log.

If you share a little code, you can get a better-informed answer.

Good luck.

Occasional Contributor
Posts: 11

Re: Capturing ANY error and processing afterwards regardless of severity

Hi Astounding!

Thanks for your response and apologies for my very tardy response!

I don't use endsas or %abort.

The error macro I use is below. The main point is that this works absolutely fine when I've anticipated a condition like an empty dataset or a missing file; but if something goes wrong and I just pick this up on the basis of &syserr then although the error log dataset is populated the file that I write this information out to is not.

/*----------------------------------------------------------------------------*/
/* Macro Name:error_processing_macro        Called As : %error_processing     */
/*                                                                            */
/* Description: Takes inputs from programs and produces error messages        */
/*              sometimes resulting in the stoppage of a process if the       */
/*              error_code is 1.                                              */
/*              Error_codes of : 1 are ERROR'S and stop processing            */
/*                               2 are NOTES and leave a blue NOTE in the log */
/*                               3 are WARNINGS and leave a green WARNING-    */
/*                                                                -in the log */
/*              To function correctly, the error condition must be reduced to */
/*              a simple condition that can be compared in a macro %IF %THEN  */
/*              clause. When that condition is MET the error has not occurred */
/*              if it is not met the error has occurred.                      */
/*              For example it is quite common to check for a file, if it is  */
/*              present the condition is met and everything is fine. If not   */
/*              an error response - either an error, note or a warning - is   */
/*              triggered.                                                    */
/*                                                                            */
/* Written by: Brian Coughlan, KNOW IT                                        */
/*       Date: 2011-05-04                                             */
/* SAS Version: 9.2                                                           */
/*                                                                            */
/*----------------------------------------------------------------------------*/
/* To use this macro prime your code with : %global error_code;               */
/*                                          %global error_msg;                */
/*                                          %let error_code=0;                */
/* Each macro that uses the error processing must start with a "wrap" :       */
/*** BMC 04/05/11 : --ERROR CHECK-- FATAL ERROR 1 ***/                        */
/* %if &error_code=1 %then %goto exit;                                        */
/*                                                                            */
/* ... and ends with %exit: prefixed in front of the mend.                    */
/* Fatal errors (1) must be followed after the macro with :                   */
/*                                       %if &error_code=1 %then %goto exit;  */
/*----------------------------------------------------------------------------*/
/* Modified:-                                                                 */
/*------------+----------------------+----------------------------------------*/
/*    Date    | By                   | Reason for change                      */
/*----------------------------------------------------------------------------*/

/*****************************************************************************************/
/*** MACRO error_processing. TAKES INPUTS FROM PROGRAMS AND PRODUCES ERROR MESSAGES    ***/
/*** SOMETIMES RESULTING IN THE STOPPAGE OF A PROCESS IF THE ERROR_CODE IS 1 (FATAL)   ***/
/*****************************************************************************************/;
%macro error_processing (error_msg=,ok_msg=,error_flag=,condition=);
/*****************************************************************************************/
/*** MACRO PARAMETERS FOR error_processing                                             ***/
/*** ERROR_MSG :THE %PUT TO WRITE TO THE LOG IN THE EVENT OF AN ERROR.                 ***/
/*** OK_MSG    :THE %PUT TO WRITE TO THE LOG IN THE EVENT OF NO ERROR (CAN BE BLANK).  ***/
/*** ERROR_FLAG:THE NUMBER OF THE ERROR CODE TO ASSIGN IN THE EVENT OF AN ERROR.       ***/
/*** CONDITION :THE CRITERIA TO APPLY TO DETERMINE IF THERE IS AN ERROR.               ***/
/***                                                                                   ***/ 
/*** EXAMPLE                                                                           ***/ 
/*** %error_processing(error_msg=EXCEL CONTROL FILE &file DOES NOT EXIST,              ***/
/*** ok_msg=EXCEL CONTROL FILE EXISTS,error_flag=1,condition=%sysfunc(fileexist(&file)));*/
/*****************************************************************************************/;
%let error_code=0;
%let message=BLANK;
%if &condition %then %do;
%if &ok_msg ne %str() %then %do;
%let message=NOTE:&ok_msg;
%put &message;
%end;
%end;
%else %do;
%let error_code=&error_flag;
%end;

%if &error_code=1 %then %do;
%let message=%str(ER)ROR: PROGRAM TERMINATED BECAUSE &CompanyPrime &error_msg;
%put &message;

%end;

%if &error_code=2 %then %do;
%let message=NOTE: &CompanyPrime &error_msg;
%put &message;
%end;

%if &error_code=3 %then %do;
%let message=WARNING: &CompanyPrime &error_msg;
%put &message;
%end;

/*** BMC 23-06-11 : --ERROR CHECKING-- ADDED TO LOG ALL ERRORS, WARNINGS AND NOTES***/;
%if &error_code GT 0 %then %do;
proc sql;
insert into &BR_CalcInputLib..error_logs
set datetimestamp="&sysdate9. &systime.",
    message="&message";
quit;
%end;

%mend Error_processing;

This is the issue I'm trapping.

%error_processing(error_msg=PROBLEM WITH THE CONTROL FILE PROCESS,
ok_msg=,error_flag=1,condition=&SYSERR eq 0);
%if &error_code=1 %then %goto exit;

and this is the code to output the file. As noted this works fine in a controlled circumstance.

proc printto PRINT="&log_lib.JobSummary__&sysdate._Job&sysjobid..lst";
proc print data=&BR_CalcInputLib..error_logs noobs;
proc print data=&BR_CalcInputLib..subset_audit noobs;
proc print data=&BR_CalcInputLib..reports_audit noobs;
run;

Super User
Posts: 5,099

Re: Capturing ANY error and processing afterwards regardless of severity

Brian,

Thanks.  I took me even longer, being out of town for a few days.

I would start this task as with any debugging task ... gather a little more information.  Here is what I would insert at the beginning of the EXIT section:

%put _all_;

data test;

x=5;

run;

proc options;

run;

proc contents data=&BR_CalcInputLib..error_logs;

run;

Not all of this will be useful (may not even run depending on what the problem is).  But dollars to doughnuts, something will pop up to indicate why there is a problem.

Good luck and post results if this doesn't point to the right direction.

Ask a Question
Discussion stats
  • 3 replies
  • 610 views
  • 0 likes
  • 2 in conversation