3

I'm reading J. Bloch's effective Java and now I'm at the section about documenting unchecked exceptions. He said that

Use the Javadoc @throws tag to document each unchecked exception that a method can throw [...].

public interface Parameters {
    //other method ommited

    /**
     * __DESCRIPTION_OMMITED__
     *
     * @throws ParameterAlreadyExistsException  If a parameter with the same name already exists in this container.
     */
    public <M> void put(ParameterMetaData<M> p, M value);
}

where public interface ParameterMetaData<ValueType>{ } is just a marker to ensure compile-time type-safety. ParameterAlreadyExistsException is a direct subclass of RuntimeException .

Here is a base implemetation of it:

public final class ParametersImpl implements Parameters{

    private final Map<ParameterMetaData<?>, Object> parameters;

    @Override
    public <M> void put(ParameterMetaData<M> p, M value){
        if(value == null)
            return;
        if(parameters.containsKey(p))
            throw new ParamAlreadyExistsException(String.format("The parameter with the name %s already exists. Value: %s", p.getClass(), parameters.get(p)));
        try{
            parameters.put(p, value);
        } catch (Exception e){
            throw new RuntimeException(String.format("Parameter insertion failed. ParameterMetaData: %s Value: %s", p.getName(), value), e);
                         // ^----------------Here non-documented exception is thrown.
        }
    }

    //remainders ommited
}

Since the Map#put(K, V) method throws and my implementaiton uses it and throws RuntimeException if somehting went wrong, how should I document that fact? And should I ever do this? Currently it may hard to say anything judging by the interface documentation why the RuntimeException is thrown.

QUESTION: How should I deal with implementation specific exceptions? should I document them?

St.Antario
  • 26,175
  • 41
  • 130
  • 318
  • 1
    Map.put() doesn't throw any checked exception. All the runtime exceptions it throws are signals of a bug in the code. You souldn't catch any of them. – JB Nizet Nov 06 '15 at 06:44
  • Related: http://stackoverflow.com/questions/824217/should-methods-that-throw-runtimeexception-indicate-it-in-method-signature?rq=1 –  Nov 06 '15 at 06:44
  • @JBNizet Actually it doesn't. But if I don't catch it, it will propagate and the client of the interface see some confusing message about putting into a HashMap which are internals. Maybe it would be good to catch it and translate into more appropriate exception? – St.Antario Nov 06 '15 at 06:54
  • 1
    That should not happen, because it's a bug, and you're supposed to test and ship without bugs. Of course it will happen, because nobody's perfect. But then having an exception pointing right to the bug is is a good thing: you'll be able to quickly identify where it comes from and fix it. Keep your code clean. You can't reasonably wrap every method call into a try-catch block just in case that method call throws an unexpected runtime exception. – JB Nizet Nov 06 '15 at 06:56

1 Answers1

3

How should I deal with implementation specific exceptions? should I document them?

You don't. Like JB Nizet indicated in a comment, this is a bug and you should test/fix these kinds of issues.

If you're worried that you're going to show internal errors to a user, you can show a generic error, something like 'Unknown error occurred'. In your logging, you can log the actual exception so your user can report the error to you and you can see what went wrong.

Stefan
  • 1,433
  • 1
  • 19
  • 30