Thank you so much @OllisGit for sharing your code. I might as well just copy it.
I'm glad that you chime in @foosel :). I also want to know if the appearance and sequence of PrintCancelled and PrintFailed are guaranteed. If so, I only have to care about PrintFailed which will greatly simplify the logic, especially my backend code, which has to deal with the possibility of lost events.
Because a cancelled print is also a failed print? A print can fail for two reasons. One is it gets cancelled by the user or due to a firmware error (in that case you'll see a cancel event before the failed event). The other is that there's a fatal error in printer communication or reported by the firmware which causes a disconnect. In that case you'll see only the failed event, not the cancelled event.
So far they weren't, if we document them they will be. However, in general, PrintFailed is always guaranteed to be fired when a print ends incomplete, so it should suffice to listen to that.
Great. It'll make my code easier. Also is it fair to say that PrintFailed is always the last event of a print? And for a successful print, the last event is always PrintDone?
Is https://github.com/foosel/OctoPrint/issues/3316 difficult to implement? If not, I'd love to have it as it'll save a ton of house-keeping work in both my plugin and server code. Hopefully other plugins can benefit from that too. If it takes too much effort, feel free to close it as I should be able to figure out a robust way to achieve the same in my code (assuming PrintFailed or PrintDone will remain the last message of Print* events for a print job).
It is in the current architecture since right now internally there's not a proper data structure for jobs yet. I have something in the pipeline to change that, but that'll be after 1.4.0