I have a small question regarding Java Exception.getMessage()
.
My code is using a client, a third party library I have no control over.
try {
thirdpartyclient.doSomthing();
return ...;
} catch (SomeCustomException e) {
if (e != null && e.getMessage() != null & e.getMessage().contains("BOOM")) {
...
}
}
I would like to handle a particular error (here SomeCustomException), but only when it contains a particular message (here BOOM, it is an example).
What I observe is that I have to write multiple checks, such as:
e != null
e.getMessage() != null
e.getMessage().contains("BOOM")
Questions:
If you catch an exception, then the exception cannot be null. So, e != null
is unnecessary.
As for what you're doing, it depends. Relying on the message of an exception is typically not a great idea. The message is not usually documented, which means it can change in the future without notice. And in mature, widespread libraries, exception messages may be localized, which means the message can be different based on the user's locale.
Needing to rely on the message of an exception to change the behavior of the code may be an indication another exception type is needed. Or that the current exception type needs to carry more information (e.g., SQLException
has a getErrorCode()
method).
Unless the library you're using documents the exception's message will contain certain specific substrings, then what you're doing is fragile.
There's no guarantee the message of a Throwable
will not be null. From Throwable#getMessage()
:
Returns:
the detail message string of this
Throwable
instance (which may benull
[emphasis added]).
However, it's possible the library you're using does make such guarantees for the specific exception you're catching.
Not sure what would be considered more efficient, other than removing the unnecessary e != null
check. But if you're doing this a lot then you can extract this logic into a utility method.
import java.util.Objects;
public final class Throwables {
public static boolean messageContains(Throwable t, String str) {
Objects.requireNonNull(t, "t");
Objects.requireNonNull(str, "str");
var msg = t.getMessage();
return msg != null && msg.contains(str);
}
private Throwables() {}
}