When quit() is called in try block, the finally block is not executed. It is only executed after normal finish or exception is raised. I got around the problem I needed to solve with addquitproc but I am curious if this is how 'finally is supposed to work in nim.
proc qproc(){.noconv.} =
echo 43
when isMainModule:
try:
#addQuitProc(qproc)
#raise newException(SystemError,"Help")
echo 41
quit()
except:
echo "exception"
finally:
echo 42
I don't claim to yet be a standard library expert in Nim, but I think that this is the intended behavior. quit is intended to be used as the final exit. It doesn't clean up resources and it doesn't handle exceptions.
For example, according to the docs if a procedure registered with addQuitProc throws an exception, this will be ignored. Also, the GC does not run after quit. Perhaps it is best to regard quit as similar to abort in C. It doesn't necessarilly clean up. It's main use is to terminate the application immediately.
It may be a good idea to structure your program so that it can exit through a normal return...
As another idea, what if you call quit in the finally block?
Yes, I agree. :)
I should note that Nim does have deconstructors, (*see my note below) but they are still, well, experimental (they require experimental mode) and have quite a few quirks. I wouldn't use them, and I am not sure how common they are in real code. My guess is that a manual cleanup is still wiser.
So far I have gathered that most people turn to finally or using the GC Finalizer. You can pass a "finalizer" proc as a second argument to new, and when the GC runs, your procedure will be called.
BUT, if you are using quit, the finalizer will never be called. If you want to have automatic cleanup, I would avoid using quit.
Here's a possibility, though. Is it possible to scrap addQuitProc, and let the finally block call your own qproc?? Then, qproc could quit?!
Like this, for example. I changed the exit code to QuitFailure and am now throwing the exception, BTW. (Hopefully what you are looking for :) ):
proc qproc() =
echo "cleaning something up"
echo "quitting next"
quit(QuitFailure)
when isMainModule:
try:
raise newException(SystemError,"Help")
except:
echo "exception"
finally:
qproc()
Outputs:
exception
cleaning something up
quitting next
Error: execution of an external program failed: { etc }.
Hope this helps!