Compiler can only do limited number of things and I am not talking about it.
Think in terms of trying to save the file you are working on before the application exits. Or notify cluster map that the node is not going to be available to process requests.
You don't exit. You work with fallible functions, and keep trying to handle errors for as long as possible.
Each function can fail, and when it fails, you propagate the error up to a point where the whole failing task can be gracefully cancelled.
e.g. if user invokes a "Print" command, and it runs out of memory, then instead of immediately crashing and burning, you can try to report "Sorry, print failed". That too will be handled fallibly, so if `message("Sorry…")?` fails, then you proceed to plan B, which may be log, then save and quit. If these fail, then finally crash and burn. But chances are that maybe print preview needed to allocate lots of memory, and other functions don't need as much, so your program will survive just by aborting that one operation.
Think in terms of trying to save the file you are working on before the application exits. Or notify cluster map that the node is not going to be available to process requests.
How does compiler factor in it?