0

There's a section about use of checked exceptions in Josh Bloch Effective Java and I find it a bit abstract to understand what he means by saying "when a user can recover from it". Authentication eg. can fail if credentials are wrong, but I wouldnt want to crash a client if a user provides wrong credentials. So is here a checked exception (by the server side) appropriate according to Bloch?

1
  • Does it actually say "when a user". It really should be whenever the situation is recoverable. There needn't be a user involved. Implementing retries for an IO error is a good example.
    – JimmyJames
    Commented Oct 17, 2023 at 20:44

2 Answers 2

5

Regarding Joshua Bloch's idea I interpret it as using checked exceptions when you can try something else when your primary action fails. Maybe a fallback or simply adjust the condition of your action to see if it succeeds.

Regarding your question about Authentication, I think it is not a good case for a checked exception. If your authentication mechanism depends on contacting a database or an identity provider(IdP), that may fail because of network issues for example, but then the problem is not authentication, it is the network, and as such you need to handle the exception and can retry or do something else to try to recover. Ultimately, if the authentication fails because the IdP is down, then your exception will probably be something like ServiceUnavailableException but not AuthenticationException. The idea is to use the appropriate exception for the situation as much as possible in order to add clarity to the code.

Strictly speaking about authentication, when you detect that it fails for any reason related to the authentication flow (e.g. wrong credentials), you normally throw the exception and expect it to bubble up until it gets caught/handled by a global exception handler. Then you can return an appropriate message to the user or return an HTTP 401 (Unauthorized). In such example, there is nothing you can do to recover from a user that gave wrong credentials. The bubble up mechanism works nicely if your exception is unchecked, but not if you use checked exceptions because you need to change the signature of all methods where the exception moves through.

Finally, I can reference as an example Spring's AuthenticationException. It is the base class for other authentication exceptions and if you see it inherits RuntimeException to avoid changing the method signatures in order to let the exception bubble up.

3
  • Can you elaborate why "The bubble up mechanism works nicely if your exception is unchecked, but not if you use checked exceptions"? Why is signature change needed for checked exceptions but not for unchecked exceptions? I heard this before, that Spring designers chose to use unchecked exceptions for this reason (to make it easier for developers to integrate Spring services).
    – TMOTTM
    Commented Oct 23, 2023 at 13:33
  • 1
    In Java, when you throw a checked exception you obligate the method where the exception is thrown to declare the exception as throws ACheckedException. This is what I mean when I say to change the signature. The complete hierarchy of method calls before you handle the exception need to change their signature and declare that such exception may be thrown. Changing method signatures to include throws ACheckedException is not always possible. An example would be to add throws ACheckedException to a method that overrides a method in an interface that you do not own.
    – silver_mx
    Commented Oct 23, 2023 at 18:04
  • 1
    On the other hand, an unchecked exception does not require you to change the method signature to add throws AnUncheckedException, which means that you do not need to change the hierarchy of method calls in order to throw your exception. You can just throw your exception and the compiler will happily allow it.
    – silver_mx
    Commented Oct 23, 2023 at 18:11
4

Here's how I understand Bloch's point:

The point of a checked exception is that the language forces you to write extra code to deal with the possibility that it occurs. That is a cost that has to be justified by something, or it wouldn't be worth having.

In the case of authentication, there are many possible reasons why the problem might be transient (resolve itself after a while): a mistyped password, a temporarily unavailable Kerberos server etc. etc. Therefore it makes sense to have a code path that prompts the user "Something went wrong - please try again in a minute".

For other errors this would make less sense; for instance, an error in hardware or in the JVM is usually severe enough that the program will almost certainly not be able to run on to achieve its purpose, so trying to prevent it from crashing is usually not worth it.

4
  • 3
    On the other hand, one could argue that a mistyped password is not an "exceptional" situation, and thus should be dealt with through the normal authentication flow. As with most things in Software Engineering, it's a both a trade-off and a judgement call. Commented Oct 17, 2023 at 7:47
  • @Kilian Foth So I understand you correctly, you would see it as a use case for a checked exception?
    – TMOTTM
    Commented Oct 17, 2023 at 8:00
  • 2
    Yes, because interaction with the user requires the program to continue and prompt them to try again, perhaps even explaining what specifically went wrong. Silently failing a log-in process would be horrible interaction design. Commented Oct 17, 2023 at 8:17
  • @JörgWMittag It suddenly occurs to me why the idea that 'exceptions should be used for exceptional circumstances' is (IMO) unconvincing and maybe even harmful. It's an idea based on semantics. I can't think of any other keyword in programming where it's meaning in English is such a concern.
    – JimmyJames
    Commented Oct 17, 2023 at 19:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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