This is needed for some improvements I'm going to make next. This commit also refactors error handling slightly to make it more easily testable, this should hopefully not result in any actual changes in behavior.