}
}
/* SMTPSendFailedException introduced in JavaMail 1.3.2, and provides detailed protocol reply code for the operation */
if (sfe instanceof SMTPSendFailedException) {
SMTPSendFailedException ssfe = (SMTPSendFailedException) sfe;
// if 5xx, terminate this delivery attempt by re-throwing the exception.
if (ssfe.getReturnCode() >= 500 && ssfe.getReturnCode() <= 599) throw sfe;
}
if (sfe.getValidUnsentAddresses() != null
&& sfe.getValidUnsentAddresses().length > 0) {
if (isDebug) log("Send failed, " + sfe.getValidUnsentAddresses().length + " valid addresses remain, continuing with any other servers");
lastError = sfe;
continue;
} else {
// There are no valid addresses left to send, so rethrow
throw sfe;
}
} catch (MessagingException me) {
//MessagingException are horribly difficult to figure out what actually happened.
StringBuffer exceptionBuffer =
new StringBuffer(256)
.append("Exception delivering message (")
.append(mail.getName())
.append(") - ")
.append(me.getMessage());
log(exceptionBuffer.toString());
if ((me.getNextException() != null) &&
(me.getNextException() instanceof java.io.IOException)) {
//This is more than likely a temporary failure
// If it's an IO exception with no nested exception, it's probably
// some socket or weird I/O related problem.
lastError = me;
continue;
}
// This was not a connection or I/O error particular to one
// SMTP server of an MX set. Instead, it is almost certainly
// a protocol level error. In this case we assume that this
// is an error we'd encounter with any of the SMTP servers
// associated with this MX record, and we pass the exception
// to the code in the outer block that determines its severity.
throw me;
}
} // end while
//If we encountered an exception while looping through,
//throw the last MessagingException we caught. We only
//do this if we were unable to send the message to any
//server. If sending eventually succeeded, we exit
//deliver() though the return at the end of the try
//block.
if (lastError != null) {
throw lastError;
}
} catch (SendFailedException sfe) {
logSendFailedException(sfe);
Collection recipients = mail.getRecipients();
boolean deleteMessage = false;
/*
* If you send a message that has multiple invalid
* addresses, you'll get a top-level SendFailedException
* that that has the valid, valid-unsent, and invalid
* address lists, with all of the server response messages
* will be contained within the nested exceptions. [Note:
* the content of the nested exceptions is implementation
* dependent.]
*
* sfe.getInvalidAddresses() should be considered permanent.
* sfe.getValidUnsentAddresses() should be considered temporary.
*
* JavaMail v1.3 properly populates those collections based
* upon the 4xx and 5xx response codes to RCPT TO. Some
* servers, such as Yahoo! don't respond to the RCPT TO,
* and provide a 5xx reply after DATA. In that case, we
* will pick up the failure from SMTPSendFailedException.
*
*/
/* SMTPSendFailedException introduced in JavaMail 1.3.2, and provides detailed protocol reply code for the operation */
if (sfe instanceof SMTPSendFailedException) {
// If we got an SMTPSendFailedException, use its RetCode to determine default permanent/temporary failure
SMTPSendFailedException ssfe = (SMTPSendFailedException) sfe;
deleteMessage = (ssfe.getReturnCode() >= 500 && ssfe.getReturnCode() <= 599);
} else {
// Sometimes we'll get a normal SendFailedException with nested SMTPAddressFailedException, so use the latter RetCode
MessagingException me = sfe;
Exception ne;
while ((ne = me.getNextException()) != null && ne instanceof MessagingException) {
me = (MessagingException)ne;
if (me instanceof SMTPAddressFailedException) {
SMTPAddressFailedException ssfe = (SMTPAddressFailedException)me;
deleteMessage = (ssfe.getReturnCode() >= 500 && ssfe.getReturnCode() <= 599);
}
}
}
// log the original set of intended recipients
if (isDebug) log("Recipients: " + recipients);
if (sfe.getInvalidAddresses() != null) {
Address[] address = sfe.getInvalidAddresses();
if (address.length > 0) {
recipients.clear();
for (int i = 0; i < address.length; i++) {
try {
recipients.add(new MailAddress(address[i].toString()));
} catch (ParseException pe) {
// this should never happen ... we should have
// caught malformed addresses long before we
// got to this code.
log("Can't parse invalid address: " + pe.getMessage());
}
}
if (isDebug) log("Invalid recipients: " + recipients);
deleteMessage = failMessage(mail, sfe, true);
}
}
if (sfe.getValidUnsentAddresses() != null) {
Address[] address = sfe.getValidUnsentAddresses();
if (address.length > 0) {
recipients.clear();
for (int i = 0; i < address.length; i++) {
try {
recipients.add(new MailAddress(address[i].toString()));
} catch (ParseException pe) {
// this should never happen ... we should have
// caught malformed addresses long before we
// got to this code.
log("Can't parse unsent address: " + pe.getMessage());
}
}
if (isDebug) log("Unsent recipients: " + recipients);
if (sfe instanceof SMTPSendFailedException) {
SMTPSendFailedException ssfe = (SMTPSendFailedException) sfe;
deleteMessage = failMessage(mail, sfe, ssfe.getReturnCode() >= 500 && ssfe.getReturnCode() <= 599);
} else {
deleteMessage = failMessage(mail, sfe, false);
}
}
}