I have this code:
try {
do_stuff();
return do_more_stuff();
} catch (UnsupportedEncodingException e) {
throw CustomException.programmer_error(e);
} catch (ProtocolException e) {
throw CustomException.programmer_error(e);
} catch (MalformedURLException e) {
throw CustomException.programmer_error(e);
} catch (SocketTimeoutException e) {
throw new CustomException(e);
} catch (IOException e) {
throw CustomException.unexpected_error(e);
}
I now need to have all those catch blocks in another similar function. What is the best way to avoid duplication here?
Note that the code inside the two try blocks is not very similar.
Also I can't really put the set of catches higher up.
Note, I'd prefer to avoid:
try {
do_stuff();
return do_more_stuff();
} catch (Exception e) {
handle_exception_via_rtti(e);
}
Don't Repeat Yourself (DRY): Using DRY or Do not Repeat Yourself principle, you make sure that you stay away from duplicate code as often as you can. Rather you replace the duplicate code with abstractions or use data normalization. To reduce duplicity in a function, one can use loops and trees.
It's safe to say that duplicate code makes your code awfully hard to maintain. It makes your codebase unnecessary large and adds extra technical debt. On top of that, writing duplicate code is a waste of time that could have been better spent.
Personally I'd try to make the
do_stuff();
return do_more_stuff();
part conform to a more general format in order to apply Strategy (as a pattern).
Then you can refactor all the places where you call this kind of block so that they can call a more generalized block (where the catches are laid out just once).
Note, I'd prefer to avoid:
Then either just live with it, or wait until JDK7 comes with Multicatch so that you can rewrite like:
try {
do_stuff();
return do_more_stuff();
} catch (UnsupportedEncodingException | ProtocolException | MalformedURLException e) {
throw CustomException.programmer_error(e);
} catch (SocketTimeoutException e) {
throw new CustomException(e);
} catch (IOException e) {
throw CustomException.unexpected_error(e);
}
You can alternatively also move this into the constructor of CustomException
and do a (nasty) global catch, but then you'll need to add a bunch of (nasty) if/else
blocks to determine the type of the exception cause. All with all, I'd just prefer to stick with the way as you already did.
Update: another alternative is to split/refactor the lines which can potentially throw the exception as separate tasks into another method blocks throwing CustomException
. E.g.
try {
do_stuff_with_encoding();
do_stuff_with_url();
do_stuff_with_ws();
// ...
return do_more_stuff();
} catch (SocketTimeoutException e) {
throw new CustomException(e);
} catch (IOException e) {
throw CustomException.unexpected_error(e);
}
...
public SomeObject do_stuff_with_encoding() throws CustomException {
try {
do_stuff();
} catch (UnsupportedEncodingException e) {
throw CustomException.programmer_error(e);
}
}
public SomeObject do_stuff_with_url() throws CustomException {
try {
do_stuff();
} catch (MalformedURLException e) {
throw CustomException.programmer_error(e);
}
}
public SomeObject do_stuff_with_ws() throws CustomException {
try {
do_stuff();
} catch (ProtocolException e) {
throw CustomException.programmer_error(e);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With