make sure cleanup is done on exception