using exceptions for errors for consistency with other IO libs and we're bound to the IO moand anyway