refactor to use less panics, return more errors