phpmailer error codes for outcome processing - email

I am building a mailout capability and it is working OK as far as it goes. However, I want to distinguish between various potential (high level) outcomes in order to determine what happens to each message after the current send attempt.
This must be a common requirement so I seem to be missing something pretty obvious, but I can't find anything that addresses it, either here or via Google or on PHPMailer site or .. . Possibly because there are so many questions about specific errors that I just can't find anything useful in all the other results.
At very high level:
Attempt send, and assess resulting error/result. Identify whether this message has been sent, must be retried later, or failed permanently.
- success -> update message status as 'SENT: OK'
- sent, but some issues (e.g. one recipient failed, others processed OK)-> 'SENT: some error'
- failed, due to temporary problem (e.g. connection problem, attachment open) -> 'TRY LATER'
- failed, due to message-specific problem that we should NOT try to resend-> 'FAILED: some error'
As I was unable to find an existing resource with e.g. a table of errors, I spent some time working through the phpmailerException code to try to build one myself, but it's not simple because a) they don't appear to have been designed in terms of this kind of grouping logic, b) it is not easy to uniquely identify a particular error: PHPMailer provides human-friendly messages, which are different in different languages, rather than an identifiable code - given that my solution will need to work across different language installations that's a problem!
Obviously SMTP itself provides a range of errorcodes which I could potentially use for this purpose, but how do I access these via PHPMailer? (This would work for me as I only use SMTP at this point - however, this would NOT work if other message transport like sendmail was used, so I would prefer a PHPMailer solution)

If you want individual result codes for individual address, you really need to send each message separately. If you do get errors on some recipients, they will be listed in the ErrorInfo property - look in the smtpSend function to see how the error string is assembled. I agree that it's not especially easy to parse that info out. The error messages in PHPMailer are generally more for the developer than the end user, so the translations are not that significant. You can get slightly more information about errors if you enable exceptions rather than relying only on return values.

Related

CalDAV protocol synchronization and behavior of different clients

i am currently trying to implement a „simple“ readonly CALDAV-interface for a system. But the synchronization protocol and the CALDAV-clients give me some headaches.
The main test client i use is the macos-calendar (sierra).
The initial handshake (DAV principle, calendar lookup) and inital load of data is working. I get some REPORT:calendar-query requests.
The issue is the incremental sync after initial load. There are two approaches:
Via WebSync-extension (REPORT:sync-collection and sync-token prop)
my main issue here is that provisioning the sync-token from the server is not trivial in my system. Changes and New data is not an issue, but physical deletion (not yet logged in the user context) and changes in the scope of group- and/or role-assignments. Maybe i need to consider to invalidate in complex cases the sync-token and let the client resetup without sync-collection?
A nasty workaround could be to retain the calendar item IDs send to the client and check on each request for their existence and responds if necessary with a not found per deleted/out of scope calendar item. But this would mean i store client-state on the server which doesnt sound right and might be error prone.
Via basic protocal synchronization (respond to REPORT:calendar-query and propfind (depth=1) requests no webdav-sync active)
this is also working already in principle for new and changed data. But the macos-calendar doesnt remove items which are not part the collection response (propfind with depth=1). According to the protocol the client should determine the deleted items and remove them, but it doesnt do it in my case. Any ideas here?
For my system currently it would be ideal to use this approach though the performance might be not the ideal one.
With ios-Calendar i face another issue:
Initial handshake is somehow working as the requests in the network are coming and are answered.
But than a MKCALENDAR request is coming (instead of a calendar-query or propfind for items) which answer with 403 as i also dont provide it in the Allow-header of the options response. the request looks like this:
MKCALENDAR /services/cal/_userid/220EDB4A-F00C-41C9-B78F-10781BBA77E4/ HTTP/1.1
Host: 127.0.0.1:8003
Content-Type: text/xml
User-Agent: iOS/10.0.1 (14A403) dataaccessd/1.0
<?xml version="1.0" encoding="UTF-8"?>
<B:mkcalendar xmlns:B="urn:ietf:params:xml:ns:caldav">
<A:set xmlns:A="DAV:">
<A:prop>
<B:calendar-free-busy-set>
<NO/>
</B:calendar-free-busy-set>
<D:calendar-order xmlns:D="http://apple.com/ns/ical/">1</D:calendar-order>
<A:displayname>Kalender</A:displayname>
<B:calendar-timezone>BEGIN:VCALENDAR
 ...deleted....
</B:calendar-timezone>
<B:supported-calendar-component-set>
<B:comp name="VEVENT"/>
</B:supported-calendar-component-set>
</A:prop>
</A:set>
</B:mkcalendar>
Nothing is happening afterwards.
Anyone experiencing this as well? Why ios-calendar tries to do a mkcalendar though i have a calendar-collection as resource-type?
With Thunderbird Lightning:
Initial handshake with the calendar-collection is working
A propfind-and multiget request for items is answered with iCal-Items.
But they are not displayed and in the error log i receive:
Warnung: CalDAV: Get failed: CalDAV: Error: got status 200 fetching calendar data for Debug Proxy, null
(text in german: error code: 0x80004005) Warnung: Fehler beim Lesen von Daten für Kalender: Debug Proxy. Allerdings ist dieser Fehler wahrscheinlich vernachlässigbar, daher versucht das Programm fortzufahren. Fehlercode: 0x80004005. Beschreibung: CalDAV: Error: got status 200 fetching calendar data for Debug Proxy, null
(text in german: error code: READ_FAILED) Warnung: Fehler beim Lesen von Daten für Kalender: Debug Proxy. Allerdings ist dieser Fehler wahrscheinlich vernachlässigbar, daher versucht das Programm fortzufahren. Fehlercode: READ_FAILED. Beschreibung:
http channel Listener OnDataAvailable contract violation
a similiar response is though working in macos-calendar – could it be some encoding issue?
Any hints are highly appreciated!
This is indeed a pretty broad question. But let me try to address some stuff:
Via WebSync-extension (REPORT:sync-collection and sync-token prop) my main issue here is that provisioning the sync-token from the server is not trivial in my system
Even if it is hard for you, you should really try to come up with something here. Even if this means storing some extra info on the server. Sync-collection is way more efficient.
(Idea: Maybe you can at least set a flag when something actually got deleted and only then expire the sync-token?)
Via basic protocal synchronization (respond to REPORT:calendar-query and propfind (depth=1))
Which one, calendar-range-query or PROPFIND? Completely different things ...
this is also working already in principle for new and changed data. But the macos-calendar doesnt remove items which are not part the collection response (propfind with depth=1).
If we are talking about a calendar-range-query, the client cannot proactively delete items since it doesn't know whether they just left the range (vs being deleted).
With PROPFIND it should do this. If you have proof it doesn't, maybe create another question with all the relevant details.
With ios-Calendar i face another issue: ... a MKCALENDAR request is coming ...
This probably means that it can't find the default scheduling calendar, no calendar at all, none with a proper component-type property. Or all the same for todos (Reminders app, same account). What is the payload of the MKCALENDAR?
Hard to diagnose w/o details, if you can't figure it out, ask a specific question on this with all the relevant details included (e.g. the XML you send in response to the home query).
Thunderbird Lightning
Can't say much about this, probably depends a lot on the version and what extensions you are using. AFAIK many people use the ScalableOGo Thunderbird extensions to get proper Cal/CardDAV with Thunderbird.
For Thunderbird/Lightning you may want to turn on calendar.debug.log and calendar.debug.log.verbose in the advanced config editor and restart. You can find it in Options > Advanced > General > Config Editor. This will get you more detailed http requests and information about what failed. You can also hook up the remote debugger and look at the network monitor, or set breakpoints in the code.
With Thunderbird/Lightning please note that we are using a mix of previous and current versions of the webdav-sync draft. I can't say much from the error message as is given it is very general, but it does look like there is something unexpected in the results.
Maybe it makes sense to compare the handshake between an existing server (like sabre/dav) and the client, then see where the difference between your communication and theirs is.
Also, you may be interested in the CalDAVTester from Apple, which checks server interoperability. Note however that it does contain various apple specific tests. The folks at CalConnect are working together with Apple to make it more generally usable and to split out the Apple-specific tests. Given your server is read-only, don't expect everything to work, but you can hunt for fixing specific tests.

FIX Message Can 35=X does not have Symbol or SecID/SecIDSource

Hi I need help to understand, if 35=X message should contain Symbol/SecID within the repeating group.
The FIX Specification indicates that under the repeating group both 55 and 48/22 are optional.
I received a message from my client without a symbol tag, please help me undersatnd if that was a bad formed message
20150923-15:06:14.976 : 8=FIXT.1.19=33635=X34=19153349=SENDER52=20150923-15:06:14.63756=RECEIVER268=8279=0269=1270=99.609375271=289279=0269=1270=99.6171875271=241279=0269=1270=99.625271=154279=0269=1270=99.6328125271=139279=0269=0270=99.6015625271=268279=0269=0270=99.59375271=244279=0269=0270=99.5859375271=171279=0269=0270=99.578125271=21610=198
You are advised to treat the default FIX message and field definitions as a set of suggested definitions.
In practice, no commercial FIX counterparty uses these definitions as-is. Every counterparty I've connected to makes modifications, adding or removing fields from messages or groups, creating new fields, or sometimes adding entirely new messages. No counterparty supports every message and field.
When connecting to a counterparty, do not assume anything. Your counterparty should provide documentation on how they expect their interface to be used, and which messages and fields they will send and which they expect to receive from you.
You need to read their specs and modify your FIXnn.xml DataDictionary file to match what they will be sending you.
If their spec says they will send you Symbol and/or SecurityID in a 35=X message, you need to make sure your DD file matches that.
This page might be helpful to you. (It's technically for the C# QuickFIX/n, but the DD file is the same for all QF versions.)
http://quickfixn.org/tutorial/custom-fields-groups-and-messages.html

QuickFixn Outgoing Connection

I was hoping someone can shed some light on how the Quickfixn engine handles outgoing FIX messages... I have an outgoing connection set up, and I'm getting heartbeats. When I generate an outgoing message however, it gets rejected because it says that tag 58 is invalid for this message type... (35=AE) ... Normally, if this was an inbound connection, I could just modify the Data Dictionary and everything would be fine... but seeing as how this is an outgoing connection, plus I have my
UseDataDictionary property set to 'N' ... what does the quickfix engine use to validate the outgoing message? Can something be changed to allow the engine to pass the message ? Or is the only resolution not to include this tag in my outgoing message?
Any help on this matter would be greatly appreciated.
Edit-
The message is getting rejected by the quickfix engine. The message that I'm constructing and the respective reject message are:
8=FIX.4.4 9=400 35=AE 34=38 49=XXX 52=20130528-23:11:04.040 56=YYY 31=1.3022 32=1000000.00 39=0 55=EUR/USD 58=ABCD 60=20130528-22:34:52.000 64=20130531 75=20130529 570=N 571=ABCD 5495=0 5971=1302200.00 552=1 54=2 37=ABCD 453=3 448=LP1-DBAB 447=D 452=17 448=XXX 447=D 452=1 448=XXX 447=D 452=19 15=EUR 120=USD 10=082
8=FIX.4.4 9=130 35=3 34=38 49=YYY 52=20130528-23:11:04.283 56=XXX 45=38 58=Tag not defined for this message type 371=58 372=AE 373=2 10=033
I've seen incoming messages get rejected by the quickfix engine because the data dictionary didn't have the correct specs for the message... I thought this might be the same thing but the outgoing connection doesn't seem to use the data dictionary.
Your FIX library does not reject a message. The message is sent to the counter-party instead, which then rejects your message as invalid upon receiving and validating it. And the reason for that is because tag 58, if present, must be a part of “NoSides repeating group (tag 552), which in your case it is not, making the message ill-formed. What you have to do is send a "logically" correct message. I recommend you refer to the appropriate FIX protocol specification for a reference on how to construct a correct message.
Vlad's answer is correct, but I want to alert you to one other danger in your question.
I have my UseDataDictionary property set to 'N'
I am 90% sure you don't want to do this. Whatever you think you're gaining by using =N is probably based on a misunderstanding of something.
Without a DD, you can't read messages with repeating groups, because the engine won't know what fields go in what group.
In practice, every venue uses repeating groups. Therefore, you'll need to set UseDataDictionary=Y and you need to specify an xml file with DataDictionary=<file>.
The only reason we allow =N in QF/n is to be consistent with QF/C++ and QF/j.

Apache Camel mail to identify auto generated messages

I'm looking for a way to identify auto generated messages like Outlook's "Out of office" replies.
I stumbled upon a header called "Auto-submitted" that's supposed to do the trick, but Camel doesn't seems to provide this header in the "Message" object. Reference: http://www.iana.org/assignments/auto-submitted-keywords/auto-submitted-keywords.xml
Is it possible to know if a message is auto generated or human generated?
I don't know Apache Camel, but I can tell you that there is no simple and safe way to detect automated email messages in general. Headers like auto-submitted are an indicator, but unfortunately lots of automated scripts do not add them. I once had to write an out-of-office implementation that should not send ooo replies to any automated messages (mailing lists, spam, newsletters, etc.). Here is what I finally came up with, maybe this helps in your case as well:
Sender address regular expressions that indicate automated senders:
"^owner-"
"^request-"
"-request#"
"bounce.*#"
"-confirm#"
"-errors#"
"^no[-]?reply"
"^donotreply"
"^postmaster#"
"^mailer[-_]daemon#"
"^mailer#"
"^listserv#"
"^majordom[o]?#"
"^mailman#"
"^nobody#"
"^bounce"
"^www(-data)?#"
"^mdaemon#"
"^root#"
"^news(letter)?#"
"^webmaster#" (role address - may not be a good indicator in your case)
"^administrator#" (role address - may not be a good indicator in your case)
"^support#" (role address - may not be a good indicator in your case)
Headers that indicate automated messages if they exist:
list-help
list-unsubscribe
list-subscribe
list-owner
list-post
list-archive
list-id
mailing-List
x-facebook-notify
x-mailing-list
x-cron-env
x-autoresponse
x-eBay-mailtracker
Headers that indicate automated messages if they have a special value:
'x-spam-flag':'yes'
'x-spam-status':'yes'
'X-Spam-Flag2': 'yes'
'precedence':'(bulk|list|junk)'
'x-precedence':'(bulk|list|junk)'
'x-barracuda-spam-status':'yes'
'x-dspam-result':'(spam|bl[ao]cklisted)'
'X-Mailer':'^Mail$'
'auto-submitted':'auto-replied'

Proper way to convey error messages during calls to a REST service?

I'm writing a REST based web service, and I'm trying to figure out the best way to handle error conditions.
Currently the service is returning HTTP Errors, such as Bad Request, but how can I return extra information to give developers using the web service an idea what they're doing wrong?
For example: creating a user with a null username returns an error of Bad Request. How can I add that the error was caused by a null username parameter?
According to the HTTP spec, the text that comes after the three digit response code, the "Reason-Phrase", can only be replaced with a logical equivalent. So you can't respond with 400 null user and expect anything useful to happen. Indeed, The client is not required to examine or display the Reason- Phrase.
In general, the HTTP response entity (typically the page that accompanies the response) should contain information useful to the client to guide them forward, even when the response is an error. On the web, most such errors are HTML, and are devoid of machine readable information, but most browsers do show the error to the user (and SO's error page is pretty good!).
So for a primarily machine readable resource you have two options:
Pass a human readable message anyway. Return 400 Bad Request with a HTML response, which the client may opt to show to the user. It's dead easy but it's a bit like throwing an unchecked exception, it passes all the hard work to the client, or indeed the end user.
Allow clients to recover. Return 400 Bad Request with a machine readable response which is part of your API, so clients can recover from known error conditions. This is harder, like throwing a checked exception, it becomes part of the API, and it allows clients to recover gracefully if they want to.
You could even make the server support both scenarios by defining a media type for the machie readable error recovery document, and allow clients to "accept" them: Accept: application/atom+xml, application/my.proprietary.errors+json
Clients that forget the mandatory field can opt in to getting machine readable errors or human readable errors by choosing to Accepting the error media type.
It's stated in the HTTP spec that most error codes should return some basic text that gives a clarification of why the error is being returned. The basic Java Servlet Spec defines the HttpServletResponse.sendError(int Code, String message) for this purpose.
String desc = "my Description";
throw new WebApplicationException(Response.status(Status.BAD_REQUEST).entity(desc).type("text/plain").build());