Currently, in D7 and D8 if a queue worker throws an exception it is uncaught. That means the entire PHP process dies. There is an upside to that: It means the item being processed will not be deleted from the queue and can simply picked up by another worker later, after it expires. That is, however, the only upside and easily outweighed by the whole "PHP breaks" downside. (Which has, incidentally, now cost me and my client several hours of swearing because our queue workers talk to outside systems, which is one of the most likely things to break and throw exceptions.)
It's also dead simple to fix, so I don't know why we haven't. The solution? Catch the exception, log it, don't delete.
The attached patch does so. It does not call releaseItem() on the assumption that if there's an exception you probably want to wait a bit before trying again; if a 3rd party service is down, for instance, you want to give it time to come back up before bombarding it with failing connection attempts. Instead, we simply allow the item to expire and get picked up on its own.
I'm pretty sure the same patch will apply to both D7 and D8, but I'm including a version rolled against D7 anyway for completeness. This should get committed to both versions.
Attachment | Size | Status | Test result | Operations |
---|---|---|---|---|
queue-exception.patch | 851 bytes | Idle | PASSED: [[SimpleTest]]: [MySQL] 57,670 pass(es). | View details | Re-test |
queue-exception-d7-do-not-test.patch | 763 bytes | Ignored | None | None |