Knowledge base

How a binding reports an error

API error reporting
An exception in C++, a success flag in C

Two error models in one interface. In C++ any error throws an exception, and the object is unusable afterwards — it is discarded and created anew. In C functions return a success flag, and the reason is given by …GetLastError and …GetLastErrorType — the connection, the message and the recipient each have their own.

The consequence is the same for both: there is no partial recovery inside an object, and the unit of success is the submission batch. That is why the manual advises keeping a batch to no more than 5,000 recipients: a failure affects fewer addresses.

The main trap is repeating the call on the same object. After an error the object is unusable in both bindings: repeating on it will not help, you need a new object — and resubmitting the whole batch.
What the Hub does. It does not use the bindings; when submitting over SMTP, the node’s reply to a command reports the error.
Recommended values

How to tell there was an error:

Binding Signal What to do with the object
C++ an exception discard it
C a FALSE return, then …GetLastError free it with …Free
The two error models and the object being unusable after an error come from the manual (§ 7.4, § 7.5); the batch size advice is § 7.1. The conclusion about the unit of success is ours.
Example configuration
# C: text and type of the connection's last error
if (!PmtaConnSubmit(conn, msg)) printf("%s %d", PmtaConnGetLastError(conn), PmtaConnGetLastErrorType(conn));
The error type is one of the PmtaApiERROR codes declared in PmtaApi.h.
yellow — — directive names, blue — blocks. They are highlighted the same way in the text of the card.
Compatibility
PowerMTA 6.0
described in the manual of this version · platform: any
The vendor does not state the first version for every directive — there is no note here. The name also appears in the 5.0 edition of the manual.
How to check on the node
Find the list of binding error codes:
grep -rn 'PmtaApiERROR' /opt/pmta/api/include/ | head
The codes are declared in the binding header: the program decides what to do with the batch by the type.
In the Hub
Cost of a mistake
safe: a wrong value breaks nothing
Scenarios
Connect a sending platform