views:

301

answers:

3

I'm using SAS 9.2 on OpenVMS to connect to an external data source over a socket specifed with a filename statement:

filename extsrc SOCKET "extserver:port" recfm=v;

data foo;
infile extsrc;
input;
.... some statements to read stuff ...;
run;

This works (as it should) 99% of the time. However, once in a while the program that is supposed to be listening on the remote port isn't. Currently this causes the program to exit with an error:

Error: Connection refused.

After which we try again, and it usually works. However, this is becoming tedious so I'd like to detect this error in the program and deal with it there. Does anybody know of a way to detect this type of error in SAS?

I've tried checking the validity of the fileref extsrc using the fileref() function, but that just returns -20005 , which means that the fileref is assigned but does not point to a local file (which is true). The error only becomes apparent when I use the fileref in a datastep, so I'd like to do something along the lines of:

data _null_;
rc=infile extsrc;
if rc=0 then do;
  //whatever I want to do;
end;
else do;
  //throw some error and try again later;
end;
run;

[update1] I'm trying the suggestions done below, but in true heisenbug fashion the problem has failed to crop up over the last few days, so I'm not sure what the final solution is yet. [/update1]

[update2] The error finally cropped up again. As per cmjohns answer, the value of syserr is 1012 after this error occurs. I'll now watch the value of syserr, and try again a fixed number of times if it fails. [/update2]

[update3] I've had some code up an running for a few days now that works. The additional problem was that (of course) if &syserr gets a value higher than 6 an error condition has occured, so depending on your errorabend/noerrorabend setting this causes the program to end completely, or it causes the program to continue with obs=0 in syntaxchek mode. Both are undesirable. The solution is to set options noerrorabend nosyntaxcheck before the datastep that produces this error. Additionally, if the error occurs I have to clear filename extsrc and reassign it. Finally, once this piece of code is complete I restore errorabend. If I restore nosyntaxcheck this causes SAS to detect the previous error condition and switch to syntaxcheck mode at that point which is also undesirable. [/update3]

+2  A: 

Have you tried testing the value of &syserr. Anything not 0 generally indicates a problem.

You can see return values here. Judging by the list I'd guess a 1012 or 1020 is what you are getting during the socket error.

cmjohns
I'm currently looking into this to see if it fixes my issue
jilles de wit
cmjohns
+1  A: 

Can you test for the data foo? If there is no data then you can set a retry loop, if data exists, continue?

Something like:

doitagain:

(insert your socket code here)

/*see if ds exists*/

%if not %sysfunc(exist(data.foo)) %then %do ;

/*if the ds does not exist then*/

%put WARNING: The file does not exist! ;

%goto doitagain;

%end;
AFHood
Yes that Is indeed my plan, but first I need some way to reliably detect that the reason dataset foo does not exist is this socket problem. I still want to error out reliably if something else is wrong.
jilles de wit
Can you do a combination of testing for the existence of the data and parsing the error if the data is not there. Therefore, if the data isn't there and the error isn't what you expect, die..?BTW, don't forget to limit the number of iterations on the loop. My example above did not do that.
AFHood
+1  A: 

I know this is a stale thread, but:

SYNTAXCHECK is nice to have; instead of running naked because of the &syserr (actually &syscc) issue, you can just clear it to last-known-good value once you're past that sensitive section of code.

Here are the relevant bits of code for when I had to gracefully handle locked-table errors from DB2:

/*** temporarily disable ERRORABEND and SYNTAXCHECK ***/
options NOERRORABEND NOSYNTAXCHECK ;

/* save &syscc for laster restoration */
%let presyscc=&syscc;

%do until (...);
  /* do a task, handle some possible errors */
%end;

/* restore &syscc */
%let syscc=&presyscc;

/*** re-enable ERRORABEND and SYNTAXCHECK ***/
options ERRORABEND SYNTAXCHECK ;