# Refactoring Tip: Take Advantage of Propagating Exceptions

Sooner or later, any student learning Java learns that Java exceptions are propagated until reaching a handler. What are the consequences of that?

One consequence is that sometimes an exception only needs to be thrown from one place, and, by refactoring, you can make your program do the same thing and pass all the tests with fewer lines.

The word “propagate” suggests a spreading out in all directions. For example, if you throw a pebble in the middle of a pond, there are going to be ripples, roughly circular, radiating out. A duck swimming in a pond also causes ripples in the water.

But an exception propagates in only one direction through the call stack, up or down, depending on your visualization preference.

For example, suppose you’re running a Java program on the command line. Suppose `main()`

calls `subroutineA()`

which calls `subroutineB()`

which calls `subroutineC()`

, which throws an exception.

As it happens, `subroutineC()`

doesn’t handle the exception. Maybe `subroutineB()`

does. Or if not, maybe `subroutineA()`

can handle the exception. Or if not, how about `main()`

?

If none of those can handle the exception, the program terminates, the Java Virtual Machine (JVM) displays the “stack trace” and shuts down, and you’re back at the command prompt.

Most likely, `subroutineC()`

doesn’t always throw an exception. It probably depends on some condition being true or not. Maybe `subroutineB()`

can check that condition before calling `subroutineC()`

.

But it probably doesn’t do us any good for both `subroutineA()`

and `subroutineB()`

to check for that condition if all they’re going to do is throw the same exception as `subroutineC()`

.

Of course this is a toy example, and you might be thinking that you would never write such an obvious redundancy in your own Java programs.

A better example is the `Fraction`

class. That class is useful for so many examples. Even if you have no use for fractions in your Java programs, the example should feel more realistic.

A fraction is of course a number like *a*/*b*, where *a* is any integer and *b* is any nonzero integer. Examples of fractions include −1/2 and 4099/537. The `Fraction`

constructor takes two integer parameters: one for the numerator and the other for the denominator.

Let’s say we’ve already written the constructor, the `equals()`

override, the `toString()`

override, and the addition, subtraction and multiplication functions, and they all work correctly and pass all the tests.

So now it’s time to work on division. The pertinent formula is (*a*/*b*)/(*c*/*d*) = *ad*/*bc*. For example, (1/2)/(3/7) = 7/6. But *c*/*d* must not be 0. If it is, the division function should throw an exception.

Let’s say we have a test that requires `ArithmeticException`

for division by zero, with a non-null message, to pass. So we write:

` public Fraction divides(Fraction divisor) {`

if (divisor.numerator == 0) {

String excMsg = "Can't divide " + this.toString()

+ " by 0";

throw new ArithmeticException(excMsg);

}

long numer = this.numerator * divisor.denominator;

long denom = this.denominator * divisor.numerator;

return new Fraction(numer, denom);

}

That works well enough, passes the tests. There’s apparently no opportunity for refactoring here.

When division by zero occurs, the stack trace should look something like this:

java.lang.IllegalArgumentException: Can’t divide 1/7 by 0

at fractions.Fraction.divides(Fraction.java:159)

… 28 elided

Another very useful arithmetic function is the reciprocal function. The reciprocal of *a*/*b* is *b*/*a*. For example, the reciprocal of 3/8 is 8/3. It should be quite easy to implement in the `Fraction`

class.

But watch out: 0 has no reciprocal. Trying to take the reciprocal of 0 should cause an `ArithmeticException`

. So we write:

` public Fraction reciprocal() {`

if (this.numerator == 0) {

String excMsg = "Can't take reciprocal of 0";

throw new ArithmeticException(excMsg);

}

return new Fraction(this.denominator, this.numerator);

}

It works, it passes the tests, and there’s no opportunity for refactoring here.

The stack trace for trying to take the reciprocal of zero looks like this:

java.lang.ArithmeticException: Can’t take reciprocal of 0

at fractions.Fraction.reciprocal(Fraction.java:209)

… 28 elided

Let’s review the formula for multiplication: *a*/*b* × *c*/*d* = *ac*/*bd*. As it turns out, division is just multiplying the dividend by the reciprocal of the divisor. We can refactor the division function this way:

` public Fraction divides(Fraction divisor) {`

if (divisor.numerator == 0) {

String excMsg = "Can't divide " + this.toString()

+ " by 0";

throw new ArithmeticException(excMsg);

}

return this.times(divisor.reciprocal());

}

All the tests pass. But doesn’t our `Fraction`

constructor also check that the denominator is not zero? It turns out that we have a redundancy here just like in the `subroutineC()`

toy example.

We can delete the zero check from the division function and from the reciprocal function, and rely instead on the constructor to throw an exception in either the case of trying to divide by zero or take the reciprocal of zero.

Of course the exception message will be a lot less specific. But who’s the exception message for and what does it need to say?

Whether the exception occurs in the context of working in an integrated development environment like NetBeans or while using the `Fraction`

class in a REPL (like the local Scala REPL), you’re not going to have any trouble figuring out what the dividend is.

I think that the important thing about the exception message in this case is that it indicate that the problem was division by zero. Any other detail in the exception message is just noise.

So I think that the benefit of fewer lines in the `Fraction`

class outweighs the loss of the more specific exception messages. If you disagree, you should write tests that check more of the exception message besides that it’s not null nor an empty `String`

.

So we rewrite `divides()`

thus:

` public Fraction divides(Fraction divisor) {`

return this.times(divisor.reciprocal());

}

And `reciprocal()`

thus:

` public Fraction reciprocal() {`

return new Fraction(this.denominator, this.numerator);

}

For both of these we rely on the `Fraction`

constructor to reject zero as a denominator. The stack trace for division by zero is accordingly longer.

java.lang.ArithmeticException: Denominator 0 is invalid or unavailable

at fractions.Fraction.<init>(Fraction.java:482)

at fractions.Fraction.reciprocal(Fraction.java:209)

at fractions.Fraction.divides(Fraction.java:166)

… 28 elided

I got these stack trace quotes from my local Scala REPL, which omits its specific “frames.” Since neither `reciprocal()`

nor `divides()`

handles the `ArithmeticException`

“propagated” from the `Fraction`

constructor, the JVM looks to the Scala REPL to handle the exception, which it does by displaying the lines of the stack trace you presumably have the power to change.

We should keep all our tests that check whether the division and reciprocal functions are throwing exceptions for division by zero. In general, we should tolerate a lot more redundancy in our test classes than in our source classes.

I hope this article has given you a better understanding of what it means for an exception to “propagate” through the call stack. With that understanding, you’ll be better able to recognize refactoring opportunities that involve relying on exception propagation to reduce duplication.