0

I am designing a library that abstracts a typical CRUD http service named FooService.

In this library I am throwing different exceptions like FooServiceClientException for network related errors or FooServiceObjectNotFound when trying to retrieve an object by a non-existing id. I also have a FooServiceException from which all other FooService*Exception inherit.

So basically the question is which exception(s) should the public methods of this library throw?

// throwing the generic FooServiceException
public FooObject getById(int id) throws FooServiceException {...}

// throwing concrete ones
public FooObject getById(int id)
       throws FooServiceClientException, FooServiceObjectNotFoundException {...}

PS: in this case the library would be written in Java, if the language may affect answers due to different approaches in different languages.

3

Throwing a generic exception like FooServiceException makes your method signature easy to read, but you're also assuming the caller is not likely going to want to differentiate. If he did, he could still do so, but he'd have to pilfer through your code to find out which specific implementations of FooServiceException are thrown. Don't make the caller do that! That is why we can't have nice things!

On the other hand, if your method getById is throwing FooConnectionTimeoutException, FooConnectionPoolExhaustedException, FooTableNotFoundException, FooServiceObjectNotFoundException, clearly something is not right about this either. But fear no more, my good OP! There is a solution.

You can organize exceptions by type, then throw a reasonably generic exception for each type possible. In other words, have FooConnectionTimeoutException, FooConnectionPoolExhaustedException, FooTableNotFoundException all derive from FooDatabaseException. Your method signature then becomes:

getById(int id) throws FooServiceObjectNotFoundException, FooDatabaseException;

See how nice this is? Callers wanting to cover any and all exceptions would look no further than handling just FooServiceObjectNotFoundException and FooDatabaseException. Callers wanting to perform a different action upon FooServiceObjectNotFoundException can do so no qualms.

You can further organize according to necessity if you want to be more detailed, but the level of detail is entirely up to you. The key point here being that you have full control over how specific you want your exceptions to be. As a general rule, try to reduce the number of exceptions thrown to 3 or less. Anything beyond that is somewhat unnecessary, especially if many of the exceptions are related to the same type of issue (unexpected problems, business errors, invalid input, etc.).

0

The exception specification is an addendum to the return value, so it should follow similar guidelines.

I would suggest that you use the least specific type that satisfies the needs of the consuming code. In your case that might be FooServiceException, but it's equally plausible that Exception or Throwable is sufficient. You don't detail the members of FooServiceException, so I can't tell.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.