BookmarkSubscribeRSS Feed
K_HARI__PRASAD
Calcite | Level 5

Hi,

I have a data set with follwing mails.

mail_nomail_id
1abc@some.com
2def@some.com
3ghi@some.com
4jkl@some.com

I want to send the mails to all ids. But if the mail id is not correct for second reconrd i.e, def@some.com then it should not stop the excution and it has to send from the third record.

Could any one suggest how to write an exception.

11 REPLIES 11
Patrick
Opal | Level 21

I'll be very interested in the answers to your question and it's something I have to find a solution for as well in my current project.

In my understanding the process is asynchronous and SAS is simply "handing over" the send email request to the email server. There is no other response than the email server accepting the request. There is no feedback to SAS whether the email address was actually valid and the email had been sent successfully.

What this means is that an invalid email address won't impact on your SAS process - but on the other hand your SAS process will not know if the email address was valid.

Happy to hear from others how to get such a confirmation from an email server. Currently my approach is that if sending an email and I don't see in "my data" that someone took action then I'm going to send a follow-up email after some time to an admin account which I know for sure that it's valid. And I will send these emails as long as I don't "see" that action hasn't been taken on the data I can analyze.

gergely_batho
SAS Employee

Set the FROM address to a valid account that is accessible by an administrator.

This way you will get a notification email about unknown recipients.

To automatically fetch those notification emails with a SAS program (using POP3 or IMAP protocol), and then populating/updating a database... Not straightforward.

SAS Digital Marketing does all this automatically.

K_HARI__PRASAD
Calcite | Level 5


Hmm.. This wouldnt help out Smiley Happy .

FILENAME hm_mail email lrecl=3200 type='text/html';

%macro send_email;

data _null_;   

set emails;

file hm_mail;

  put '!EM_TO!' mail_id;
  put '!EM_SUBJECT!' '';
  put 'Hello';
  put '<br>';
  put 'This is a system-generated message. Do not reply to this e-mail.';
  put '!EM_SEND!';
  PUT '!EM_NEWMSG!';
run;

%mend send_email;
%send_email;

In this code can we write any if condition(if we get error) after the put '!EM_SEND!'; statement???????????

gergely_batho
SAS Employee

OK, now I see the problem. You want to handle the send-errors immediately inside the data step.

Is it an option to write a macro cycle, and sending only 1 message in 1 data step?

Even in that case it is hard to recognize, when and why a message failed. You get a warning in the SAS log, but I think the only macro variable you have is: &syserr. It is 0 for succesfull and 4 for failed messages..

Also it would be possible to redirect the SAS log into a file, then reading it back and extracting successfull and failed messages.

Also you could try using filename(), fopen(), fput(), fwrite(), fclose() functions. Maybe they give you more information (return codes). I never tried them with the EMAIL device.

Another (probably most complicated) option: using FILENAME fileref SOCKET 'emailhost:25'. Then you can read/write from/to it - you have full controll. But then you must implement the whole SMTP protocol yourself Smiley Sad

gergely_batho
SAS Employee

I tried: You can use f...() functions to send email, but return codes do not help there either.

data _null_;

set emails;

  rc=filename('hm_mail','','email','lrecl=3200 type="text/html" to="'||mail_id||'"');

  putlog rc=;

  fid=fopen('hm_mail','O');

  putlog fid=;

  rc=fput(fid,'!EM_TO!'|| mail_id);

  putlog rc=;

  rc=fwrite(fid);

  putlog rc=;

  rc=fput(fid,'EM_SUBJECT!'|| 'Hello');

  putlog rc=;

  rc=fwrite(fid);

  putlog rc=;

  rc=fput(fid,'<br> body');

  putlog rc=;

  rc=fwrite(fid);

  putlog rc=;

  rc=fclose(fid);

  putlog rc=;

  rc=symget('SYSERR');

  putlog rc=;

run;

K_HARI__PRASAD
Calcite | Level 5


Many thank for your repley..

Can we write a IF condition by using symget('SYSERR');. I am getting the below ERROR and WARNINGs.

WARNING: Email: 550 5.1.1 <ghi@some.com>: Recipient address rejected: User unknown

WARNING: Bad email address: ghi@some.com

ERROR: No email addresses specified.

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

So here the error is I/O and when I check with SYSERR the error code is 1020..So based on this code IF SYSERR=1020 THEN can we implement this.?? If YES kinly suggest the code where to implement.

Many thanks in advance.

gergely_batho
SAS Employee

Unfortunately SYSERR macro variable is set only at the end of the data step. If you run my previous code, you can see, that I am extracting this macro variable, but the value is 0.

The only solution is to break up each email sending into a separate data step.

How many emails do you want to send? Why do you need this check? Isn't it OK if you check failed messages at the very end of the sending process?

K_HARI__PRASAD
Calcite | Level 5

I dont know the count exactly. We can take this as an Production example, which means gradually increases the size of records on time basis. So, If we want to split each record into a table its time consuming which is not the right way.

So kindly suggest if there any implimentation is possible.

gergely_batho
SAS Employee

I think this is almost as fast as running 1 data step:

options emailsys=smtp emailhost=mail.server.com emailid="sender@sender.com";

data emails;

input mail_no mail_id :$30.;

datalines;

2 wrong@wrong

1 good@goodaddr.com

;

run;

%macro cycle();

%do i=1 %to 2;/*Here 2 is hardcoded, but you can get the number of observations from the emails dataset*/

FILENAME hm_mail email lrecl=3200 type='text/html';

data _null_;

set emails(firstobs=&i. obs=&i.);

file hm_mail;

  put '!EM_TO!' mail_id;

  put '!EM_SUBJECT!' '';

  put 'Hello';

  put '<br>';

  put 'Message.';

  put '!EM_SEND!';

run;

%if &SYSERR.=0 %then %do;

  %put &i.  all OK;

%end;

%else %do;

  %put &i.  there was an error; /*you can add here one line to a database, etc*/

%end;

FILENAME hm_mail;

%end;/*%do*/

%mend;

%cycle();

K_HARI__PRASAD
Calcite | Level 5

Thanks a lot for your efforts.

Its looks, we can implement this but here "mails"data set looks as follows;

1abc@some.com
2def@some.com
3ghi@some.com
4jkl@some.com
5abc@some.com
6def@some.com
7def@some.com

As of now my code looks as follows;;;

STEP=1: Sorting the data set.

--------------------------------------------------------------------------------------------------------------------

PROC SORT DATA=mails;

BY mail_id;

RUN;

-----------------------------------------------------------------------------------------------------------------------------------

STEP=2 : Sending mails for every three hundred users after holding the triggering mails process for 2 mnts..

---------------------------------------------------------------------------------------------------------------------------------------


%macro send_email;

filename hm_mail email lrecl=32000 type='text/html';


data _null_;   
set mails END=EOF;
by mail_id;
file hm_mail;


retain numofusers 0;

if first.mail_id then do; 

     numofusers=numofusers+1;
  If mod(numofusers,300) = 0 then Timer=Sleep(120,1);

  put '!EM_TO!' mail_id;
  put '!EM_SUBJECT!' 'Test Plans have been created.';
  put 'The following test plans have been created with you as a tester.';
  put '<br>';
end;

id_link = '<a href="' ||left(strip(id)) || '">' || left(strip(id)) || '</a>' ;
put '<br>';
put id_link;
put '<br>';

if last.mail_id then do;
  put '<br>';
  put 'This is a system-generated message. Do not reply to this e-mail.';
  put '!EM_SEND!';
  put '!EM_NEWMSG!';
end;

if EOF then put '!EM_ABORT!';


run;

%mend send_email;
%send_email;

-------------------------------------------------------------------------------------------------------------------------------------

Now kindly implement your code in the step 2.

Many thanks to your time and efforts.

Sourav_sas
Quartz | Level 8

Hi guys,

 

I have small query. Like there in SYSERR we are mentioning 0 or other. Is there any way we can mention the error text instead of error code to specify the error in If statement or any other condition. I want to get mail only if that error text will arrive like for example "you are running out of memory". Only if this error will come, then I will get mail. Any solution, it will be helpful for me.

 

Thanks,

Regards

Sourav

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

SAS Enterprise Guide vs. SAS Studio

What’s the difference between SAS Enterprise Guide and SAS Studio? How are they similar? Just ask SAS’ Danny Modlin.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 11 replies
  • 3747 views
  • 4 likes
  • 4 in conversation