This is a case where the API spec doesn't always match the implementation. The unwritten rules from the source code seem to be:
- Handling of a null record can be hostile or ignored. Subclasses of StreamHandler ignore null and the MemoryHandler is null hostile. The logger never passes null to publish so it doesn't really matter what you choose.
- Any runtime exception thrown from isLoggable will escape the Handler. Which means any exception thrown from a filter escapes the publish method and is not trapped by the error manager. Notice how there is no enum ErrorManager.FILTER_FAILURE so that implies that the behavior is intentional.
- Exceptions that the publish should not throw are enumerated in the ErrorManager documentation. Most cases are formatting and writing errors.
Really publish should delegate to the error manager to determine if publish throws exceptions or not. From the Handler.setErrorManager documentation:
The ErrorManager's "error" method will be invoked if any errors occur while using this Handler.
This implies that publish should obey the behavior of the error manager which by default doesn't throw.
If you want to get an exception through Handler.reportError you have to use a sneaky throw.
public class HostileErrorManager extends ErrorManager {
@Override
public void error(String msg, Exception ex, int code) {
sneakyThrow(new Throwable(msg + ": " + code, ex));
}
@SuppressWarnings("unchecked")
private <T extends RuntimeException> void sneakyThrow(Throwable t) throws T {
throw (T) t;
}
}