 |
| ASP Pro Code Clinic As of Oct 5, 2005, this forum is now locked. No posts have been deleted. Please use "Classic ASP Professional" at: http://p2p.wrox.com/forum.asp?FORUM_ID=56 for discussions similar to the old ASP Pro Code Clinic or one of the other many remaining ASP and ASP.NET forums here. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the ASP Pro Code Clinic section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

February 26th, 2004, 07:04 PM
|
|
Registered User
|
|
Join Date: Feb 2004
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
CDO Email Errors not trapped by On Error
Hi,
I've got a problem where my apps email service is sporadic. Sometimes works like a charm, other times fails miserably.
What's supposed to happen is the following:
When an e-mail is successfully sent -- exit successfully and do nothing further.
When an error occurs on the email Send command
1) Log the error # and description, body, subject, and distribution in a table
2) Generate a message for the user explaining that the e-mail has NOT been sent, but everything else is OK
3) Give them a link to redirect them so they continue as if no error had occurred.
Unfortunately, when the e-mail fails, nothing is recorded, nor is the user notified that an error occurred.
Any ideas?
(Note: Using Access 2000 on Win Server 2003)
Here is the code for all three procedures. Sorry if the indentation is messy...
Sub Sub_Process_Email_Error(str_Redirect)
If str_Redirect <> "myFiles.asp" Then
Response.Write "The E-mail was not sent due to an error. The QAS Developer has been notified and will resend the e-mail for you.<br>"
Response.Write "All data was saved, and all other events have occurred.<br>"
Response.Write "Please click <a href=" & str_Redirect & ">here</a> to continue."
Response.End
End If
End Sub
Sub Sub_Log_Email_Error(int_Err, str_Error, str_From,str_To, str_Cc, str_Subject, str_Body, str_Redirect)
Dim rstError
Set rstError = Server.CreateObject("ADODB.Recordset")
Set rstError.ActiveConnection = obj_Connection
rstError.Open "Select * From emailFailed",,3,3 'adOpenStatic, adLockOptimistic
rstError.AddNew
With rstError
.Fields("str_From") = str_From
.Fields("str_To").Value = str_To
.Fields("str_Cc").Value = str_Cc
.Fields("str_Subject").Value = str_Subject
.Fields("str_Body").Value = str_Body
.Fields("dtm_Date").Value = Now()
.Fields("int_Err").Value = int_Err
.Fields("str_ErrorDescription").Value = str_Error
.Fields("isFailed").Value = True
End With
rstError.Update
rstError.Close
Set rstError = Nothing
Call Sub_Process_Email_Error(str_Redirect)
End Sub
Sub Sub_Send_Email(str_From,str_To, str_Cc, str_Subject, str_Body, str_Redirect)
If con_BlnEmailOn Then
If con_BlnDebugEmail Then
' Developer is debugging email functions
Response.Write "<p>"
Response.Write "<b>FROM:</b>" & str_From & "<br>"
Response.Write "<b>TO:</b>" & str_To & "<br>"
Response.Write "<b>CC:</b>" & str_Cc & "<br>"
Response.Write "<b>SUBJECT:</b>" & str_Subject & "<br>"
Response.Write "<b>BODY:</b><br>"
Response.Write "<pre>" & str_Body & "</pre>"
Response.Write "</p>"
Response.Write "<br><a href=" & str_Redirect & ">Continue</a>"
Response.End
Else
' Send Email
If IsNull(str_From) OR IsNull(str_To) OR IsNull(str_Cc) OR IsNull(str_Subject) OR IsNull(str_Body) Then
' An error occurred, do nothing
Else
' send the email message
Dim obj_Email
Dim iConf
Dim Flds
Dim int_Err
Dim str_Error
Const cdoSendUsingPort = 2
Set obj_Email = CreateObject("CDO.Message")
Set iConf = CreateObject("CDO.Configuration")
Set Flds = iConf.Fields
With Flds
.Item(cdoSendUsingMethod) = cdoSendUsingPort
.Item(cdoSMTPServer)= <remote server>
.Item(cdoSMTPServerPort) = 25
.Item(cdoSMTPconnectiontimeout) = 10
.Update
End With
Set obj_Email.Configuration = iConf
obj_Email.From = str_From
obj_Email.To = str_To
obj_Email.Cc = str_Cc
obj_Email.Subject = str_Subject
obj_Email.HTMLBody = "<pre>" & str_Body & "</pre>"
On Error Resume Next
obj_Email.Send
int_Err = Err.Number
str_Error = Err.Description
Err.Clear
Set obj_Email = Nothing
Set iConf = Nothing
Set Flds = Nothing
If int_Err <> 0 Then
Call Sub_Log_Email_Error(int_Err, str_Error, str_From,str_To, str_Cc, str_Subject, str_Body, str_Redirect)
End If
End If
End If
End If
End Sub
Thanks, Eric Bycer
|
|

February 27th, 2004, 03:18 AM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
|
|
Hi there,
Can you define "fails miserably"?
Is it possible that the CDO correctly drops the message with the server, but that it fails after that? E.G. I tell you to tell Jim something. As far as I am concerned, it is OK, because I told you to tell Jim. However, if you forget to tell Jim (or Jim just speaks Chinese), we have a problem...... ;)
Did you try to run the error handler code by throwing an error yourself? e.g. set int_Err to a non-zero value?
Imar
---------------------------------------
Imar Spaanjaars
Everyone is unique, except for me.
|
|

February 27th, 2004, 08:33 AM
|
|
Registered User
|
|
Join Date: Feb 2004
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Hi,
I suppose I should say it fails "gracefully" rather than miserably. When it fails, an e-mail is not sent, but the error handling procedure is not called, but no one knows it wasn't sent unless the receipient is later contacted. The usual error is "transport failed to connect to server" (IT has assured me that I have the correct remote server, and it does work sometimes...).
So, there's no log of the error, and no way for me to even attempt a resend.
To answer your second question, I have inserted an error, and at that point the error handler is called.
It seems as if something is going wrong with my "On Error" code, like unless I force it, it doesn't register Err.Number <> 0.
Should I not clear the error? Should I have the error handler code immediately following the .Send? I'm at a loss here, so any help you can provide will be most appreciated.
Thanks,
Eric Bycer
|
|

February 27th, 2004, 09:02 AM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 231
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Your script could be timing out, however I would have thought that if this was the case then the client would be notified of the fact with an error page. If the script does time out then it will simply exit the routine it is on without generating any form of catchable error.
To test this write to a log file just before you call obj_Email.Send then write to the same log file just after the call. When the send does fail without being handled properly take a look at the log file and make sure that the second write exists, if it is not there then you know that the script has exited before it was completed, this may be because it timed out.
Regards
Owain Williams
|
|

February 27th, 2004, 09:16 AM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 17,089
Thanks: 80
Thanked 1,576 Times in 1,552 Posts
|
|
AFAIK, the error handling code is fine. Whenever the Send method sets the Err.Number, the rest should work.
I tested this by setting the smtpserver to a non-existent server, and I got the usual "The transport failed to connect to the server" error message.
So, I still think that the error takes place after the Send method has been called. So, Send thinks everything is fine, and doesn't touch the Err.Number....
---------------------------------------
Imar Spaanjaars
Everyone is unique, except for me.
|
|

February 27th, 2004, 01:21 PM
|
|
Registered User
|
|
Join Date: Feb 2004
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
owain, Imar,
First off, thanks.
Second, I'm going to try owain's idea of writing to a log both before and after .Send. That should tell me which e-mails are failing.
And, while I suppose I could go through the log file to determine which e-mail sends failed and which did not, how can I best
a) get a list of failed e-mails populated into my emailFailed table, and
b) resend them?
If I have to do it the hard way, I can and will.
I'll try this over the weekend and see what happens.
Eric Bycer
|
|

March 1st, 2004, 07:43 AM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 231
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Instead of having an emailFailed table you could, for example, call it EmailLogs. This table would contain columns for all the information you need to know about an email (To, From, Subject, Body, etc.) with an additional column Sent which would be set to True if the email was sent with no error.
Before you send an email you could add a new row with the details about the email, then if the send succeeds with no error you could change the Sent column for that row to True. If an error is generated or the script never completes then the Sent column will default to False. Here is a simplified version of the script you could use.
Code:
On Error Resume Next
rstEmailLog.AddNew
rstEmailLog("str_From") = str_From
rstEmailLog("str_To") = str_To
rstEmailLog("str_Cc") = str_Cc
rstEmailLog("str_Subject") = str_Subject
rstEmailLog("str_Body") = str_Body
rstEmailLog("dtmDate") = Now()
rstEmailLog.Update
obj_Email.From = str_From
obj_Email.To = str_To
obj_Email.Cc = str_Cc
obj_Email.Subject = str_Subject
obj_Email.HTMLBody = "<pre>" & str_Body & "</pre>"
obj_Email.Send
int_Err = Err.Number
str_Error = Err.Description
Err.Clear
If int_Err = 0 Then
rstEmailLog("Sent") = True
rstEmailLog.Update
Else
rstEmailLog("Sent") = False
rstEmailLog("int_Err") = int_Err
rstEmailLog("str_ErrorDescription") = str_Error
rstEmailLog.Update
End If
You could then have another script that is scheduled to run as often as is required. This script would scan through the EmailLogs table looking for all emails where the Sent column is False. Again, the column would only be set to True if no error is generated and the script completes.
Code:
On Error Resume Next
rstEmailLog.Open "SELECT * FROM EmailLog WHERE Sent = False", , 3, 3
Do Until rstEmailLog.EOF
obj_Email.From = rstEmailLog("str_From")
obj_Email.To = rstEmailLog("str_To")
obj_Email.Cc = rstEmailLog("str_Cc")
obj_Email.Subject = rstEmailLog("str_Subject")
obj_Email.HTMLBody = "<pre>" & rstEmailLog("str_Body") & "</pre>"
obj_Email.Send
int_Err = Err.Number
str_Error = Err.Description
Err.Clear
If int_Err = 0 Then
rstEmailLog("Sent") = True
rstEmailLog("int_Err") = 0
rstEmailLog("str_ErrorDescription") = ""
rstEmailLog.Update
Else
rstEmailLog("Sent") = False
rstEmailLog("int_Err") = int_Err
rstEmailLog("str_ErrorDescription") = str_Error
rstEmailLog.Update
End If
rstEmailLog.MoveNext
Loop
Because of the possibility of the script timing out the results of the query might need to be returned to the client the then each email may need to be re-sent manually. This could be automated by JavaScript, however that is an entirely new thread :).
You may also want to include a counter column that would be incremented every time you try and send the email so you can see if certain emails are never being sent, these could be larger emails, or emails with large attachments that are not being sent before the script times out.
Regards
Owain Williams
|
|
 |