2

I'm developing a library for Android, which I intend to open source and naturally I want to tick all of the boxes before I publish it - so users are suitably impressed with my code. Ahem.

As with many libraries, there are certain basic configurations necessary in order for the library to function.

public static final String API_KEY = "your_api_key_here";

In the above instance, when a user passes their API key to the library, I'm putting a simple string match in for "your_api_key_here" and if it matches, I'm going to throw a RuntimeException, as they quite simply haven't read the basic instructions and I want their app to die.

Is this a valid use of a RuntimeException? If it isn't, then in Java what is?

EDIT - My motivation for posting this is due to this post, where the OP is lynched by shouts of "why!?" for asking how to throw one.

ANSWER - In this instance, it seems to be more a matter of preference than right or wrong either way - at least no one has so far objected. This scenario should only occur during the testing phase for a developer and never in production. If this wasn't the case, I wouldn't have chosen an uncaught exception.

I've marked an answer as correct due to the most upvotes and following @mech's comment below, I have created a custom ReadTheDocumentationException which provides a suitably persuasive message.

Community
  • 1
  • 1
brandall
  • 6,094
  • 4
  • 49
  • 103
  • You want to throw exception when user doesn't initialize the API_KEY right – Qandeel Abbassi Feb 21 '16 at 19:36
  • 3
    Maybe make a ReadTheDocumentationException derived from RTE? Specificity is good :) – mech Feb 21 '16 at 19:37
  • 2
    There is no One Right Way to do this. If you choose to make your library crash if the caller doesn't use it properly, then so be it, and document it. Lots of Java and Android components work this way. What the caller expects is a meaningful message in the exception to say what went wrong. – Doug Stevenson Feb 21 '16 at 19:42
  • @DougStevenson Totally agree. Still wondering what someone would consider a specific use case for RuntimeException though. It must be there for a reason. – brandall Feb 21 '16 at 19:50
  • There are a ton of reasons to throw runtime exceptions, but in general, I think it'd be better to throw a subclass. In this case it's largely opinion since you're providing a decent reason. That said, if you have other invalid configurations, I'd probably subclass and create a general `InvalidConfigurationException` with the same messaging. – Dave Newton Feb 21 '16 at 19:51
  • It's there for subclassing. – Dave Newton Feb 21 '16 at 19:52
  • @DaveNewton I agree with you. But I wonder if you'd dare to answer with an example usage, confident that you wouldn't get slaughtered and down-voted by others with different opinions. I wouldn't! :) – brandall Feb 21 '16 at 19:56
  • I added an answer with detail about how RuntimeException may be used. It's up to you to choose. – Doug Stevenson Feb 21 '16 at 19:56
  • @brandall ... I'm not sure what you're asking for an example of. There are a bunch of `RTE` subclasses throughout Java and the JVM ecosystem, including the ones mentioned in the answers. Note that I'm differentiating between "runtime exceptions" and `RuntimeException`. I don't have a problem throwing an actual `RTE` for high-level "this is radically broken" errors as long as it contains all the info required to diagnose and fix the problem. My own preference is to subclass and generalize, just like with checked exceptions, as much as possible allowing them to be `caught` at a high level. – Dave Newton Feb 21 '16 at 20:04
  • If your objective is to control how your library is being used, exceptions are the only way. Also, subclassing usually suitably impress users. – Mussa Feb 21 '16 at 20:19
  • @DaveNewton I hear you, and agree. I'm going to wait to see if someone very opinionated comes along with a counter argument before marking an answer as correct. – brandall Feb 21 '16 at 20:26
  • @Mussa I agree :) I think a ReadTheDocumentationException is probably the way forward – brandall Feb 21 '16 at 20:28

3 Answers3

7

I think you should use illegal argument exception which is subclass of java.lang.RuntimeException . You can do something like this

if(API_KEY.equals("your_api_key_here"))
    throw new IllegalArgumentException("you message here");

For more info see this

Qandeel Abbassi
  • 999
  • 7
  • 31
  • 4
    IMO this is for method calls with obviously-invalid arguments. This is more of a library configuration/setup error, which is more of an `InvalidStateException` ("the Java environment or Java application is not in an appropriate state for the requested operation"). But it's more of an opinion than anything else. – Dave Newton Feb 21 '16 at 19:47
  • 1
    `IllegalArgumentException` is for *wrong* arguments passed into a method. – Mussa Feb 21 '16 at 20:01
  • The OP didn't say that the missing configuration option was a method argument. It could be buried anywhere in the app. I wouldn't use IllegalArgument unless it is an actual argument, as the first commenter says. – Doug Stevenson Feb 21 '16 at 20:03
  • I supposed that he was using some method which accepts api key and there he checks that whether the key is initialized or not – Qandeel Abbassi Feb 21 '16 at 20:03
  • @Mussa I like this answer, as it doesn't require to catch the exception in normal usage. I *would* consider "your_api_key_here" to be *wrong*. However, you are correct that I did intend to examine this in a method/constructor, but failed to state that in the question. +1 for incite though! – brandall Feb 21 '16 at 20:06
  • @brandall Incite is arguably actually correct here ;) – Dave Newton Feb 21 '16 at 21:13
  • @DaveNewton Ha! I'm going to pretend it wasn't a typo then :D – brandall Feb 21 '16 at 21:18
  • In your example the exception will never be thrown. – Onik Feb 21 '16 at 22:48
  • @Onik Are you referring to an equality check? If so, I think he can be forgiven for Pseudo code - but matches() or equals() would be the way forward. – brandall Feb 21 '16 at 23:53
3

You should create your own exception by extending RuntimeException or any other Exception. IllegalStateException would work for a case when someone terribly misbehave.

Mussa
  • 1,463
  • 21
  • 25
2

It sounds like part of your question deals with what is the proper use of RuntimeException, and partly deals with how your library should behave if misconfigured. I'll deal with mostly the former.

In Java, there are two types of exceptions, checked and unchecked.

RuntimeException and all of its subclasses are "unchecked" exceptions, meaning there is no requirement from the compiler to catch them. You can use these to crash your process if something is very wrong. The caller can still catch and handle them on their own, so be prepared that the caller may continue to call into your lib incorrectly.

Exception and all of its subclasses (except RuntimeException) are "checked", meaning that the compiler requires the caller to catch them or declare in a method declaration that it could be thrown. You use this in cases where you expect the caller to try to recover from whatever condition caused the exception to be thrown.

In your case, you can throw a RuntimeException with a meaningful message, or a custom subclass of RuntimeException with a message to indicate to the caller exactly what went wrong and how to remedy it. It doesn't really matter what you choose, but many people choose to subclass for clarity. I'd just make sure that the exception is never thrown by surprise in order to have clear rules for engagement for your lib.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441