62

I've been interviewed recently and the interviewer wanted me to do a technical test to see my knowledge. After I finished it he gave me feedback about how I did it, which I didn't expect and I appreciated, since few interviewers do it if they don't want to hire you.

One of the things he told me that he saw bad about my code was that I used more than one try-catch block inside each method I wrote. This calls my attention since I see it interesting.

I believe at the moment that I should make try-catch blocks where there is a semantically distinguishable block of code which has one or more methods that can throw exceptions needed to be caught. The only exception to this that I followed was that if two methods throw the same exception type, I better put them in different try-catch blocks to clearly distinguish when debugging where and why an exception was thrown.

This strongly differs from what the interviewer wanted me to do. So is using just one try-catch block per method a known good practice? If it is a known good practice what are the benefits of doing it?


Please note that I would like to know if this is a known good practice. I.e. if most programmers/authors would agree that this is a good practice.

Neuron
  • 5,141
  • 5
  • 38
  • 59
Adrián Pérez
  • 2,186
  • 4
  • 21
  • 33
  • Related question: http://stackoverflow.com/questions/2737328/why-should-i-not-wrap-every-block-in-try-catch – Andrew Ferrier Sep 13 '13 at 10:53
  • I asked a similar question: [How many statements in a try/catch statement?](http://stackoverflow.com/questions/2086769/how-many-statements-in-a-try-catch-statement) – Sjoerd Sep 13 '13 at 10:54
  • 12
    I agree with your viewpoint. Interviewers are not always right. – tbsalling Sep 13 '13 at 10:54
  • @AndrewFerrier I've read the answers and the question. I think i'm not asking the same thing if that is what you mean. I want to know if that is a known good practice to do it. If that is approved for most programmers, and or is written in some renown book. – Adrián Pérez Sep 13 '13 at 10:56
  • 2
    @tbsalling Don't get me wrong. I don't say the interviewer is wrong. It's that may be I'm missing something that I don't know. – Adrián Pérez Sep 13 '13 at 10:57
  • 2
    My take would be that you should use different try/catch blocks where the behavior is different. If what is in the catch is the same in both blocks I would just use one. This of course begs the question if there is more than one try/catch block because the code is distinct as is the catch functionality, should it be broken into multiple methods. – John B Sep 13 '13 at 10:58
  • 4
    The problem with many `try` statements in method might be that your methods are too long or you rely on exceptions too heavily. If it's not that case, than I don't see his opinion as justified. – zch Sep 13 '13 at 11:00
  • See my reply in the EDIT of my answer... Well may I ask without offending you was it an interview in service based company or product based one? – dharam Sep 13 '13 at 12:13
  • 1
    It's a fairly minor issue either way. If that's his criticism then it sounds like you did pretty well in the interview :) – MikeFHay Sep 13 '13 at 15:31
  • 4
    Maybe the interviewer wanted to see how you would react to criticism in a code review setting? – Alvin Sep 13 '13 at 20:10
  • That's interesting Alvin, but I don't think it was the perfect setting in my case, for him to do it, since the technical test was sent to my email and then I did it in my home. The reply was sent in an email also. And I didn't replied to it since I didn't knew what to say and think. It's also my first time I did a test like this. – Adrián Pérez Sep 13 '13 at 20:53

7 Answers7

45

For me, two try-catch blocks makes most methods too long. It obfuscates the intention if the method is doing many things.

With two try-catch blocks, it's doing at least four things, to be precise

  • two cases for main flow (two try blocks)
  • two cases for error handling (catch blocks)

I would rather make short and clear methods out of each try-catch block- like

private String getHostNameFromConfigFile(String configFile, String defaultHostName) {
    try {
        BufferedReader reader = new BufferedReader(new FileReader(configFile));
        return reader.readLine();
    } catch (IOException e) {
        return defaultHostName;
    }
}
public Collection<String> readServerHostnames(File mainServerConfigFile, File  backupServerConfigFile) {
    String mainServerHostname=getHostNameFromConfigFile(mainServerConfigFile,"default- server.example.org");
    String backupServerHostName=getHostNameFromConfigFile(backupServerConfigFile,"default- server.example.ru")
    return Arrays.asList(mainServerHostname,backupServerHostName);
}

Robert C. Martin in 'Clean Code' takes it to next level, suggesting:

if the keyword 'try' exists in a function, it should be the very first word in the function and that there should be nothing after the catch/finally blocks.

I would definitely refactor the method with two separate try/catch blocks into smaller methods.

Mohammad Faisal
  • 5,783
  • 15
  • 70
  • 117
Bartosz Bilicki
  • 12,599
  • 13
  • 71
  • 113
  • 4
    I like more your answer since you have found what I was trying to find; i.e. a good and renown reference that suggest or encourages to write only a try-catch per method/function, and tells the reasons to do that. Seems that finally I'll learn something from my interviewer. – Adrián Pérez Sep 16 '13 at 18:31
35

I'd say that if you find yourself wrapping two separate blocks of code with try/catch you should consider refactoring those blocks into separate methods. If this is a pattern you used in your interview than perhaps you misunderstood your interviewer.

It is perfectly fine to use two try/catch blocks if the algorithm requires it. I have often used a new try/catch in a catch block to ensure a safe cleanup so a blanket statement is not possible.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
  • 6
    +1 Agreed. A method should serve only one purpose. – rocketboy Sep 13 '13 at 11:02
  • 3
    Beside, if you wrap two separate blocks of code inside a same try/catch, then you cannot implement one proper recovery algorithm in the catch block without having to distinguish between the two cases, using a "if", which kind of defeats the purpose of the catch and make it more complicated than necessary. – Yann-Gaël Guéhéneuc Sep 13 '13 at 13:46
  • 2
    This is the best answer because it recognizes the actual problem. – MirroredFate Sep 13 '13 at 17:54
  • Perfect, talks about the actual reason, Single Responsibility of methods as well. – Prasanna Mondkar Dec 18 '19 at 19:42
14

To answer your question, when we talk about modern day JVMs which are actually applying a lot of optimizations in the code, when you write some code which is inefficient then the JVM will automatically introduce optimizations.

Please refer the answer in (Java: overhead of entering/using "try-catch" blocks?).

So the good practice thing is not of much importance.

On a personal note, I believe that one must not encapsulate anything in a try-catch, static, synchronized etc blocks un-necessarily.

Let us make our code more readable to the ones who will be working on this. If an exception is caught, it is better to explicitly make it prominent that which piece of code is throwing it.

No guessing for the reader, that is why JVMs are smart, write as you want , make it better for humans and JVM takes care of the optimization part.

EDIT: I have read plenty of books and I didn't find it any place which says that one big try catch is better than multiple small ones.

Moreover, many in the developer community believe the opposite.

Community
  • 1
  • 1
dharam
  • 7,882
  • 15
  • 65
  • 93
  • 2
    Thanks @dharam, this is the kind of answer I was looking for. Each one of us have reasons to think one way or another to manipulate this try-catch blocks for better clean code, or performance. Although if people agree with you; i.e. it's not known good practice, then I find that it's not a good way to use a personal preference to judge a candidate to a job. I'd expect to be judged by what it's commonly accepted and then be told to code following the team preferences about the style of the code. I expected to learn something from the interviewer, it seems I won't. :/ – Adrián Pérez Sep 13 '13 at 16:43
9

I try to avoid duplication in catch blocks. If all the exceptions in a method receive the same treatment in the catch block, then go ahead and catch them all together. If you need to do different things with them, then catch them separately.

For example, here we can catch all exceptions together, because any kind of exception means the whole method fails:

public PasswordAuthentication readAuthenticationDetails(File authenticationFile) {
    try {
        BufferedReader reader = new BufferedReader(new FileReader(authenticationFile));
        String username = reader.readLine();
        String password = reader.readLine();
        return new PasswordAuthentication(username, password.toCharArray());
    } catch (IOException e) {
        return null;
    }
}

Whereas here, we have different fallback behaviour for each group of calls, so we catch separately:

public Collection<String> readServerHostnames(File mainServerConfigFile, File backupServerConfigFile) {
    String mainServerHostname;
    try {
        BufferedReader reader = new BufferedReader(new FileReader(mainServerConfigFile));
        mainServerHostname = reader.readLine();
    } catch (IOException e) {
        mainServerHostname = "default-server.example.org";
    }

    String backupServerHostname;
    try {
        BufferedReader reader = new BufferedReader(new FileReader(backupServerConfigFile));
        backupServerHostname = reader.readLine();
    } catch (IOException e) {
        backupServerHostname = "default-server.example.ru";
    }

    return Arrays.asList(mainServerHostname, backupServerHostname);
}

(This code exists purely to illustrate this point about catching exceptions; i beg you to disregard the fact that it is utterly horrible in other ways)

Tom Anderson
  • 46,189
  • 17
  • 92
  • 133
6

As for me, it's clearer to have just one try-catch block wrapping all the 'hazardous' code in a method. Regarding who to blame when two lines throw the same exception, you'll always have the stacktrace.

Besides, having more than one try-catch inside a method usually means having more than one return lines (which can also make hard to follow code execution at a sight), as chances are that if something goes wrong in the first try-catch, it won't make sense to keep running the rest of the code.

Here you can find some 'standard' best practices, just in case you may find them useful.-

http://howtodoinjava.com/2013/04/04/java-exception-handling-best-practices/

ssantos
  • 16,001
  • 7
  • 50
  • 70
5

It's also important to consider the context of the code. If you're writing code with heavy IO then you may need to know which parts of the code are failing. I didn't see anywhere yet a point that try...catch is meant to give you a chance to recover from a problem.

So if you get an IO exception in reading from one file, you may want to retry reading. Same with writing. But if you had one large try...catch you wouldn't know which to retry.

CLo
  • 3,650
  • 3
  • 26
  • 44
4

This is another thing that often starts Java-flamewar... ;-)

Basically, for the performance matters only throwing exceptions. So using few try-catch blocks shouldn't affect a performance at all. In some opinion writing code that way obfuscates the code and does not even recall "clean code", in others opinion it's better to use try only for lines which can actually throw any exception.

It's up to you decide (or the team convention).

Eel Lee
  • 3,513
  • 2
  • 31
  • 49