Production Ready Macros for SAS Application Developers
mf_abort.sas
Go to the documentation of this file.
1 /**
2  @file
3  @brief abort gracefully according to context
4  @details Can configure an abort mechanism according to site specific policies
5  or the particulars of an environment. For instance, can stream custom
6  results back to the client in an STP Web App context, or completely stop
7  in the case of a batch run.
8 
9  @param mac= to contain the name of the calling macro
10  @param type= enables custom error handling to be configured
11  @param msg= message to be returned
12  @param iftrue= supply a condition under which the macro should be executed.
13 
14  @version 9.2
15  @author Allan Bowe
16 **/
17 
18 %macro mf_abort(mac=mf_abort.sas, type=, msg=, iftrue=%str(1=1)
19 )/*/STORE SOURCE*/;
20 
21  %if not(%eval(%unquote(&iftrue))) %then %return;
22 
23  %put NOTE: /// mf_abort macro executing //;
24  %if %length(&mac)>0 %then %put NOTE- called by &mac;
25  %put NOTE - &msg;
26  %if not %symexist(h54sDebuggingMode) %then %do;
27  %let h54sDebuggingMode=0;
28  %end;
29  /* Stored Process Server web app context */
30  %if %symexist(_metaperson) %then %do;
31  options obs=max replace nosyntaxcheck mprint;
32  /* extract log error / warning, if exist */
33  %local logloc logline;
34  %global logmsg; /* capture global messages */
35  %if %symexist(SYSPRINTTOLOG) %then %let logloc=&SYSPRINTTOLOG;
36  %else %let logloc=%qsysfunc(getoption(LOG));
37  proc printto log=log;run;
38  %if %length(&logloc)>0 %then %do;
39  %let logline=0;
40  data _null_;
41  infile &logloc lrecl=5000;
42  input; putlog _infile_;
43  i=1;
44  retain logonce 0;
45  if (_infile_=:'WARNING' or _infile_=:'ERROR') and logonce=0 then do;
46  call symputx('logline',_n_);
47  logonce+1;
48  end;
49  run;
50  /* capture log including lines BEFORE the error */
51  %if &logline>0 %then %do;
52  data _null_;
53  infile &logloc lrecl=5000;
54  input;
55  i=1;
56  stoploop=0;
57  if _n_ ge &logline-5 and stoploop=0 then do until (i>12);
58  call symputx('logmsg',catx('\n',symget('logmsg'),_infile_));
59  input;
60  i+1;
61  stoploop=1;
62  end;
63  if stoploop=1 then stop;
64  run;
65  %end;
66  %end;
67 
68  /* send response in Boemska h54s JSON format */
69  data _null_;
70  file _webout mod lrecl=32000;
71  length msg $32767;
72  if symexist('usermessage') then usermessage=quote(trim(symget('usermessage')));
73  else usermessage='"blank"';
74  if symexist('logmessage') then logmessage=quote(trim(symget('logmessage')));
75  else logmessage='"blank"';
76  sasdatetime=datetime();
77  msg=cats(symget('msg'),'\n\nLog Extract:\n',symget('logmsg'));
78  /* escape the quotes */
79  msg=tranwrd(msg,'"','\"');
80  /* ditch the CRLFs as chrome complains */
81  msg=compress(msg,,'kw');
82  /* quote without quoting the quotes (which are escaped instead) */
83  msg=cats('"',msg,'"');
84  if symexist('_debug') then debug=symget('_debug');
85  if debug=131 then put "--h54s-data-start--";
86  put '{"h54sAbort" : [{';
87  put ' "MSG":' msg ;
88  put ' ,"MAC": "' "&mac" '"}],';
89  put '"usermessage" : ' usermessage ',';
90  put '"logmessage" : ' logmessage ',';
91  put '"errormessage" : "aborted by mf_abort macro",';
92  put '"requestingUser" : "' "&_metauser." '",';
93  put '"requestingPerson" : "' "&_metaperson." '",';
94  put '"executingPid" : ' "&sysjobid." ',';
95  put '"sasDatetime" : ' sasdatetime ',';
96  put '"status" : "success"}';
97  if debug=131 then put "--h54s-data-end--";
98  rc = stpsrvset('program error', 0);
99  run;
100  %let syscc=0;
101  %if %substr(&sysvlong.,8,2)=M2 %then %do;
102  /* M2 stp server does not cope well with endsas */
103  data _null_;
104  abort cancel 0 nolist;
105  run;
106  %end;
107  endsas;
108  %end;
109 
110  %put _all_;
111  %abort cancel;
112 %mend;