Catching generic Exception in a toString implementation - bad practice? - java

I have a domain model class which has a toString implementation that looks like this:
public String toString() {
try {
return getX() + "\n"
getY() + "\n"
getZ(); //etc.
} catch(Exception e) {
throw new RuntimeException(e);
}
}
The methods getX(), getY() and getZ() are not simple getters, they can perform lookups in the background, generally a lookup to a static map of predefined key-value pairs. Some of them had throws SomeCheckedException in their signatures.
My impression is that this is bad practice and a "code smell". The fact that toString() even needs this check is to me a symptom of bad design. But I'm asked by a colleague, what exactly is wrong with catching the generic Exception in a toString(), since the caught Exception is propagated further.
I believe it violates at least the KISS principle, since a simple method like toString() here is indicated as requiring special exception handling.
So is it code smell to have a catch-all block in a toString()?
Answers I found were either for the general scenario of catching generic Exception and I agree with most of them, that if you're doing a generic error handling mechanism or a batch then it's expected to work on generic exceptions. This argument was unconvincing in our discussion, so I'm curious of other opinions.

For the toString() method, catching Exception is not necessarily a bad practice. However, re-throwing it is the problematic part.
The contract for toString() is:
... In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read...
In Effective Java 3rd Edition (Item 12), Bloch further insists:
When practical, the toString method should return all of the interesting information contained in the object.
So, if this requires calling methods that may throw checked exceptions, then so be it, and it makes a lot of sense to catch these exceptions.
However: raised checked exceptions provide information about the state of the object. Consistently with the goal of toString, it may be a good idea to include the exceptional condition in the message returned by toString.
As for why it's a bad idea to throw exceptions from toString, this post provides a great answer.
Recommendation: Catch the checked exceptions using their specific exception type, and integrate this fact in the toString() message, instead of propagating it.

Yes this is bad practice.
The intention of the toString method is to provide a programmer readable representation of your class. You shouldn't include any method calls in this method, including getters.
In fact, I would consider not autogenerating these methods smelly, but assuming you are not comfortable or able to use an IDE that would produce them for you, I would recommend including a reference to all the fields on the object, and the class name of the object, as is done by the intellij toString method

The main reason not to catch generic Exception at any place is that it will include RuntimeExceptions too, which should not be catched on normal circumstances, because they always represent a bug in the program. It's better to let them be propagated and arise, so that the developer can notice it and eventually fix it.
I don't know if any additional good practice checks shall be applied in the case of toString methods, but I'm sure at least the general rule should be applied.
So, the best practice is always to catch only checked exceptions, and then either recover, either rethrow them, or either rewrap them into another exception (which is your case).

Should the "normal flow" be interrupted by a failing toString() method? If the answer is no, you should make the toString() method "work". Catching an exception an reflecting this in the result is one possibility, or a simple log output.

Related

Should I declare all exceptions thrown from a method in the method signature or just the super class of the exceptions?

When I throw checked exceptions from a method should I just declare the super class of the exceptions in the method signature or all the different types? If I have the following exceptions:
private class SuperException extends Exception {
}
private class SubExceptionOne extends SuperException {
}
private class SubExceptionTwo extends SuperException {
}
Should the method signature be:
void confirmAccount() throws SubExceptionOne, SubExceptionTwo;
or
void confirmAccount() throws SuperException;
In the last method signature, how do I tell other developers what exceptions that could be thrown from the method? If the different sub types need different handling?
The interface should be as stable as possible. So probably Super. Many libraries use the "Super" strategy, because exception specs cause far more annoyance in maintainability than readability or safety they add. Even the IOException is a Super that nearly all Java library code uses instead of declaring more specific exceptions. (But when they do declare more specific exceptions, it's because the contract is that more general IOExceptions won't be thrown. Read on.)
You might list Sub1 and Sub2 if you really do want to say each of those exceptions can be thrown, but don't want to say that any derivative of Super can be thrown. Perhaps Sub1 is NumberCrunchException and your method calls crunchNumbers() and users of your method can be assured that's the only exception-ful thing your method does. In that case the specific strategy is better.
If the different sub types need different handling, then definitely declare the two different exceptions. Never expect the developer using your method to guess that you are actually throwing different types of exceptions.
If you declare two distinct exceptions, and the user knows from the Javadoc that they are actually descendents of the same class, the user may choose to catch them both with a catch (SuperException e) rather than two individual catch clauses. But it depends on the user's choice.
If you don't declare them separately, your IDE is not going to add the appropriate #Throws to your Javadoc comment. And your Javadoc will therefore only indicate that you're throwing SuperException, which will leave the user in the dark. Solving this by just putting it in the text of the comment is not a real solution. If any tool is using reflection to determine what your method throws, it will not see the individual exceptions in the array returned from Method.getExceptionTypes().
If the functionality expected of the different exceptions is more or less the same and it's just a matter of how they will appear in the logs, it may be better to just use the parent exception, with different messages.
The throws clause is there to convey useful information to the calling method about what might go wrong during invocation of this method. That means that how specific you are will depend on how much information you want to convey; and that will be application-dependent.
For instance, declaring throws Exception is almost always a bad idea: the information this conveys is just "something might go wrong", which is too vague to be useful. But whether calling classes are going to need perfectly fine-grained information in the throws clause is something you need to decide by looking at your program. There's no set answer.

Would a Mandatory<T> be a useful addition alongside Guava's Optional<T>?

I was looking at Guava's Optional class and its justification, and I wondered whether a similar class to fail-fast when representing values that must not be null would be helpful. I can't find any discussion of this idea so I thought I'd ask here.
My first attempt would try to stay in the style used by Guava, a Mandatory<T>, exposing a static factory of(T t). This method throws NullPointerException if called with a null argument.
My particular interest is nailing down the semantics of interface methods in respect of null handling. I think that whether to accept null arguments or not is a design decision that should be specifiable in the interface so that client code can be designed accordingly and can avoid duplicating precondition checking logic. As such, an interface using this class might have methods like
fire(Mandatory<Employee> employee);
and a client might call
fire(Mandatory.of(unfortunateEmployee));
I suspect that the Mandatory type would be quite easy to find using aspects and the like to hook in further checks before invocation if it was absolutely vital that such marked method arguments should not be null.
I've also considered annotation-based approaches such as fire(#NotNull Employee employee) but the implementations I've seen require additional wiring up of validators.
So, the questions... does this idea exist anywhere already? If not, have I missed something obvious that undermines it? Or a better idea to achieve this?
fire(Mandatory<Employee> employee);
If you had a method with this signature, you could still call fire(null); it'd just be that you'd have a null of type Mandatory<Employee> instead of type Employee. You haven't actually improved safety at all; you've just added a redundant layer of wrapping.
If you want to enforce that a parameter is required, good practice is to use e.g. Preconditions.checkNotNull as the first thing in your method to immediately throw a NullPointerException if the value is null.
adding a Mandatory.of method that throws NPE
Using your T variable will already throw a NullPointerException, so what's the point?
How to specify that a parameter is required as part of the contract?
Javadoc has been used for this for a long time.
Yeah, but I want to enforce it.
You have too much time on your hands. That aside...
#NotNull is the "new way". You can use AOP to wire not-null validation automatically for the desired methods. Here are a couple of great implementations:
http://blog.solidcraft.eu/2010/09/getting-rid-of-null-parameters-with.html
http://janistoolbox.typepad.com/blog/2009/12/aopvalidationnotnull.html

Programmatically distinguish exceptions

The type of an exception is often enough to handle it properly (for example you try to open a file and get a FileNotFoundException). However there are cases where you might catch multiple exception of the same type. For example, an IllegalArgumentException that can be caused by more than one argument. The IllegalArgumentException does not add any additional methods (or public fields) to the Throwable interface (accoding to the online javadoc) which means that the only information that you can rely on are the nested exception (which may or may not exist) and the message (which is for human consumption).
I don't like the idea of extending IllegalArgumentException to add structured information to it, because other people would have to learn the new class. And I don't like the idea of littering projects with very specific exception classes.
Using the message field is also a bad idea because it's not meant for programmatic access.
I think IllegalArgumentException should have included details such as the class function and argument(s) in question. And in general custom exceptions should provide additional detail (other then just their type) for a more fine grained exception handling.
What are considered generally the best practices for designing exception classes, and handling exceptions of the same type?
As a general rule, I think it is ideal to have one class of exception per "type of action a caller might reasonably want to take". Of course, for one's own custom exceptions there could be a boolean or enum field providing some extra disambiguation, rather than creating trivial subclasses.
In your specific case I'm not convinced that trying to handle the exception is a good idea. RuntimeException and its subclasses usually represent coding issues, and the same is true of IllegalArgumentException. If the argument is illegal it shouldn't be passed in in the first place.
If you're in a situation where you're not sure if an argument is valid (maybe it's user input, or maybe you don't know the specific object you're calling the method on) then a better approach would be to have some way of checking the validity of the argument before passing it. Rather than say "do this" and catch the exception, ask "can I do this?" before calling.
Exception classes should be designed so as to provide all that is needed when they are caught. Note that try/catch statements are actually a form of type switch, so in general it is cleaner to create additional exception classes rather than confuse program logic by nesting too many if's within catch clauses.
It has to be said that catch clauses are not very convenient if you want to organize your error handling code in an object oriented fashion, so there are different trade offs to keep in mind.
Note that standard exception classes do have information available on what piece of code caused the exception, even though I would not advise you to base on it your error handling logic.
If the current exception was thrown in a catch clause for a different exception this should be available with the getCause() method, while the getStackTrace() should provide access to the stack of calls that were active when your exception was thrown.
Again I don't advise you to use this information except for debugging purposes.
Its true that the predefined exception classes are very general. But if you want more specific details about the exceptions then you should go for user defined exceptions. you should create your own exception classes with any level of details!
here is the pseudo code:
public class TooManyArguments extends exception{
public String toString(){
return ("..whatever information you want to give for this exception..")'
}
}
and whenever you encounter exceptional situation throw an instance of this class
throw new TooManyArguments();

Correct Java Exception for a malfomed string

I have a method that should only accept strings of a certain format. When the format is invalid, I want to throw an Exception. I'm quite new to Java, so am not sure what the correct type of exception to use here is. I found there is a IllegalFormatException, which based on the name sounds right, though the docs make me rather unsure about this. What is the correct Exception class to use here?
The method in question is the constructor of a PropertyId class, which takes one string argument, which should match '/^p[1-9][0-9]*$/i'. It should behave essentially the same as this equivalent in Python.
I'd prefer using an Exception provided by the standard library, unless there really is none that is appropriate, or it is generally agreed on that in my case a new Exception derivative should be created.
I am with #TwoThe. IllegalArgumentException is the way to go. In fact, I actually don't think there should be much debate. This situation is exactly what IllegalArgumentException was made for.
IllegalFormatException is misleading for sure, but that (and its subclasses) is for a completely different case--when the format string you provide for output is invalid.
Generating your own custom exceptions should only be done with great care. Only when you have a special case where no standard exceptions apply. That isn't true here, and you don't want your clients to have to deal with non-standard stuff unless absolutely necessary.
Remember, with great power comes great responsibility.
This appear reasonable to me, from the Javadoc for IllegalFormatException
Unchecked exception thrown when a format string contains an illegal
syntax or a format specifier that is incompatible with the given
arguments. Only explicit subtypes of this exception which correspond
to specific errors should be instantiated.
As #BasvandenBroek points out, this is appropriate for String which contain format information, rather than checking the format of a String.
However, it may be that it's parent IllegalArgumentException is best. NumberFormatException is close, but not approriate, and it's parent is also IAE.
Note: you can create your own sub-class of IllegalArgumentException
public class StringValidationFailedException extends IllegalArgumentException {
public StringValidationFailedException(String message) {
super(message);
}
}
Try IllegalArgumentException.
There are many exceptions in Java, but it sounds like you may need a custom exception depending on what you mean by format. There are many examples of that on this site. Here are just two links.
How to create a custom exception type in Java?
How to define custom exception class in Java, the easiest way?

Java: Exception in constructors: Problematic or not?

I am recently thinking about if throwing constructor from Java is good or not. Currently this is what I gathered:
Can constructors throw exceptions in Java?
Here, Mr. StackOverflow (aka Jon Skeet) does not seem to hold anything against it, but he did hint about having subclass throwing exceptions. What will happen (anything bad?) when subclass throws exceptions?
http://futuretask.blogspot.com/2006/05/java-tip-10-constructor-exceptions-are.html
This blog post "Constructor Exceptions are Evil" tells me a way to show that constructor exceptions could be dangerous. However, the example seem to be really esoteric. Is there any real danger here?
I am thinking that if static factory methods (Effective Java 2nd ed., Item 1) are used instead of public constructors, we could safely remove the exceptions from constructors to the static factory method. Is this a valid way to avoid constructor exceptions and is this useful or used in anywhere?
Any inputs are helpful & appreciated. Thanks!
There is nothing wrong with exceptions in constructors (or factory methods, either way is fine). sometimes, doing too much work in a constructor can be a poor design, and may make sense to move to a factory method.
the only thing that point 2 proves is that exceptions in constructors are not an adequate security mechanism for protecting a class from evil usage. however, there are any number of ways to subvert such a design, which is why the only way to truly run secure code in java is running with a SecurityManager. so point 2 is just a straw man argument.
My point about a subclass throwing an exception is a situation like this:
public class Parent {
private final InputStream stream;
public Parent() {
stream = new FileInputStream(...);
}
public void close() throws IOException {
stream.close();
}
}
public class Child extends Parent {
public Child() {
// Implicit call to super()
if (someCondition) {
throw new RuntimeException();
}
}
}
Now the Child class really should call close() if it's going to throw an exception. Of course, if close() is overridden by yet another layer of inheritance, that could also cause problems. Just another example of how inheritance gets messy.
I still think it's basically fine for constructors to throw exceptions. Even your second link was more about an evil way of capturing the not-successfully-constructed object rather than really about constructor exceptions being evil - it certainly doesn't give any reasons for not throwing exceptions from constructors. It doesn't even give the messy situation I mentioned.
Factory methods could potentially help, but as far as the caller is concerned the result is the same: they don't get to see the partially-constructed object. Unless you really need to do something like clean-up on an object which was constructed but then failed some element of validation, I don't think that should be a reason to use factory methods instead of constructors. (There are other reasons to do so, but that's a different matter.)
I believe throwing exceptions from constructors is fine, more so the one's which checks for the preconditions to a successful object creation, example IllegalArgumentException.
However, I do not believe that constructors are the right place to handle business logic or throw business exception/ custom exceptions.
As for the reasons cited to not throw an exception, IMHO they are quite contrived; bottom line is if a careless developer wishes to do something evil he can find numerous ways to do it and there's no stopping till the developer does a self review of the code/ follows best practices.

Categories

Resources