add an API, use fine-grained exceptions