Every integration demo looks the same. An order comes in on the website, appears in the ERP, syncs to the accounting ledger, and triggers a shipping label. Everyone nods. The project gets approved.
Then, eight weeks after go-live, someone notices that a customer's address change never made it from the CRM to the ERP. Three shipments went to the old warehouse. Nobody got an alert, because nothing technically broke — one API call timed out at 2:14 a.m. and no one was watching.
This is the real work of integration, and it's the part that gets cut when budgets tighten. The happy path is maybe a third of the effort. The other two-thirds is deciding what happens when things go wrong.
Three kinds of failure, three different responses
Lumping all errors together is why error handling gets ignored — the log fills with noise and people stop reading it. Separate them.
Transient failures are network blips, timeouts, rate limits, and brief outages. Nothing is wrong with your data. The right response is to try again, with increasing delays between attempts. These should almost never reach a human.
Data failures are records that the receiving system legitimately refuses: a missing tax code, an item number that doesn't exist, a currency the ERP isn't configured for. Retrying will fail forever. Someone has to fix the data or the configuration.
Logic failures are the sneaky ones. The call succeeded, but the outcome was wrong — a duplicate invoice, an update applied out of order, a partial write that left two systems disagreeing. No error was raised at all.
If your integration treats all three the same way, you'll either retry things that can never succeed or alert humans about things that fixed themselves.
Retries only work if your operations are idempotent
Idempotency is a clunky word for a simple idea: doing something twice should produce the same result as doing it once.
When a request times out, you genuinely don't know whether the other system processed it. Maybe it did and the confirmation got lost. If you retry blindly on a "create invoice" call, you may have just created a second invoice.
The fix is to attach a unique key to every operation — an order ID, a transaction reference, something stable and generated by the sender. The receiving system records keys it has already processed and ignores repeats. Now retries are safe, and safe retries eliminate most of your overnight failures without anyone lifting a finger.
If you're buying an integration or evaluating a middleware platform, ask directly how idempotency is handled. The answer tells you a lot about how seriously the vendor takes production reality.
Build an error inbox, not an error log
When a record exhausts its retries, it needs somewhere to go. In technical terms that's a dead-letter queue. In business terms it should be an inbox a non-engineer can work.
A log entry that reads `HTTP 422: constraint violation on field vat_id` is useless to the controller who can actually fix it. A usable error record says: Invoice 10482 for Northwind couldn't post to the ERP because the customer's VAT ID is missing. Add it in the CRM and click Retry.
A workable error record includes:
- What business object failed, in plain language, with a link to it in the source system
- Why it failed, translated out of API-speak
- Who is responsible for fixing it
- A retry button that re-runs the single record once the data is corrected
- A timestamp, so aging items can be escalated automatically
Then assign the queue a human owner and a review cadence. An unowned error queue grows to a thousand items and becomes permanently unreadable. Reviewed every morning, it stays at zero to five.
Reconciliation catches what alerts miss
The failures that cost the most money don't throw errors. A webhook never fires. A filter quietly excludes a record type. A scheduled job doesn't run because the server rebooted. The system can't alert you about work it never knew existed.
The defense is boring and effective: a daily count comparison. How many orders did the website record yesterday? How many landed in the ERP? How many invoices posted to the ledger? Any gap, however small, gets investigated.
This takes a few hours to build and tends to find problems that have been running silently for weeks. For high-value flows — revenue, inventory, payroll — it's not optional.
Decide who gets paged, and for what
Finally, agree in advance on severity. A single customer record stuck in the queue is a next-business-day item. Zero orders synced in four hours during business hours is a phone call. Writing this down before go-live prevents both alert fatigue and the quiet disaster nobody noticed until month-end close.
Good integrations aren't the ones that never fail. They're the ones that fail loudly, in one place, with a clear owner and an obvious next step.
If you're running data between a website, CRM, and ERP — or you're about to — and you can't say today who sees the failures, that's worth a conversation. Reach out to Infraxio and we'll walk your flows with you and show you where the silent gaps are.
