Duplicate invoice references when creating multiple invoices


#1

When creating multiple invoices in a loop…
… one at a time via the API using route https://api.freeagent.com/v2/invoices [POST]
… although all those invoices are created perfectly…

PROBLEM

… they are all allocated the SAME reference.

NOTES

  • All works fine when creating one at a time, e.g. through Postman
  • FreeAgent settings are for global references: which is what we want and works in all other circumstances

Can anyone explain why we might be seeing this behaviour please?


#2

Hi Ben,

My name is Dave and I am one of the Support Engineers here at FreeAgent.

Urgh, it sounds like you might have hit against a classic race condition.
When a POST request is received to the v2/invoices end-point, we create a new in-memory invoice with a reference that follows on from your last persisted invoice.

If two POST requests are received in rapid succession, we’ll (unfortunately) create two in-memory invoices, both with the same reference, since neither invoice has yet been written to the database. The first invoice will be persisted successfully, whilst the second will fail since it no longer has a unique reference.

It sounds like we need to take a closer look at how multiple POST requests are handled at our end, to ensure there’s no crossing of the streams. I’ll raise this with our API team right away, though for now, you might want to consider adding a small sleep statement in your loop to allow time for the first invoice to be created (and persisted), before the second request arrives. Sorry, I know that’s somewhat cludgy. Alternatively, you could explicitly pass the reference attribute as part of your POST request, so you could enforce uniqueness at your end.

I hope this helps and sorry for the confusion, Ben!


#3

Thank you for your response Dave.

I suspected it might be something like that. What would you suggest as a suitably ‘small’ sleep duration?


#4

My non-scientific guesstimate would be ~1 second. Could you give it a try and let us know if it does the trick?


#5

Ha, thanks.

This is proving tricky - at least for me. I’m using Node.js and a ‘promise’ mechanism (axios) to call the FA route within a loop.

There is no concept of ‘sleep’ in JS so having to workaround. Someone must have encountered this situation before?

Any pointers welcome…


#6

Pretty sure I’ve resolved this now.

Turns out a ‘sleep’ is not required.

The problem was that we were not calling the invoices route ‘sequentially’ via the ‘promises’ mechanism we’re using. We’re using node.js and axios in particular. Needed to restructure the code to ensure we fired off the axios() promise requests sequentially. Doing that means we avoid the ‘race’ condition (or ‘pyramid of doom’ as its known in the world of Javascript and promises).

Working for now though we’ll be doing more testing. Hope this is helpful to others in a similar situation.