functional, with most error handling