lots of refactor for error handling