throw a custom exception so it's easier to catch