How to avoid many catch catch blocks in java

I am very new to java and the idea of ​​try catch blocks handles exceptions.

This is roughly what I am running out of, and there just has to be a better way:

try { JSONObject jsonObject = new JSONObject(jsonString); int aCount = jsonObject.getInt("acount"); String devTok = jsonObject.getString("dt"); String qURL = jsonObject.getString("qu"); try { DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); Key qKey = KeyFactory.createKey("qu", qURL); int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber); //..etc.. more try catch blocks needed } catch (EntityNotFoundException e) { e.printStackTrace(); } } catch (com.google.appengine.repackaged.org.json.JSONException e) { e.printStackTrace(); } 

There are more catch catch blocks built in in the same way, so at the end there is just a piece of catch blocks. How else to handle exceptions, Eclipse continues to ask me to get around using the catch catch block or the “Add throws declaration”.

Sometimes I want to catch certain exceptions, for example, if it cannot find the entity, I want to print something like "Entity not found", and if the JSON string cannot be parsed into an object, I want to print something like "Unable to parse JSON ".

(I use objective-c, where the delegation methods for failure, or the method returns null, and you passed a pointer to the [pointer to] NSError object to be "populated", Is somewhere to learn about try-catch?)

+6
source share
10 answers

If all you do is catch them and print a stack trace regardless of the type of exception, you can simply wrap the code in one big try / catch block. To save a lot of “catches”, you can catch java.lang.Throwable , which is an interface that implements all exceptions. If not, you can get a catch for each type of checked exceptions, the code you are calling, and handle them specifically.

Eclipse continues to ask you about this because Java code will not compile unless the checked exceptions are caught or declared by the called caller.

+ Adding a comment to the answer (thanks, Paul Tomblin):

In applications with quality quality, you will register a trace by adding some logic in which you correctly handle the exception using an alternative thread and / or re-wrapping it in another exception and throwing it, etc. It all depends on the specific problem you are trying to solve.

+6
source

The idea behind exception handling is that you can handle errors at points in your program flow where you can deal with them meaningfully. Instead of checking every return value of the function, like in C, where most of the time you can’t do anything reasonable, except passing the error on, you install the try / catch block at reasonable points in your program:

Basically, whenever there is a point at which you can react to an error, then catch that error and pass on everything else. Thus, error handling is called only when there is a plausible recovery from the error.

For example, in the worst case scenario, if any error stops your program from meaningful execution, then you will catch almost nothing and just let the OS handle the situation (well, maybe one try / catch attempt to create a friendly error message).

Example (in C ++, sorry, I cannot type Java blind):

 int main() { try { while (masterloop()) { } catch (...) { LOG("Fatal program error, terminating!"); // nothing else we can do! } } /* lots of program logic */ void process_image() { try { Image im = load_image_from_disk(); /* ... */ } catch (const OutOfMemoryExc & e) { LOG("Not enough memory to process the image."); return; } catch (const DataErrorExc & e) { LOG("Could not read the image data."); return; } catch (...) { throw; // pass everything else along } } 

In this example, we can try to process the image and fail for some reason (memory or inability to read the image). In this case, we simply return without doing work, and let the program continue gracefully. All other errors propagate to the highest point. Most importantly, we do not have to constantly put the current image processing function with error checks and answers, enough for any code to throw one of our two good exceptions and no longer worry.

Moral: If you have try / catch blocks absolutely everywhere, you are doing it wrong.

+4
source

I know there are many answers here and they do a good job of how to structure try / catch blocks. However, I think one of the things that bothers you is significant ... indentation and code growth (... because I know that this is not indentation or the amount of code, but the implied complexity, wrapping it and rearranging it it grows longer and longer between the attempt to open and close the catch, and I can not say this fear).

A way around this is to reorganize individual bits of code into functions. I know this is a simplified answer, but it is a good way to isolate individual tasks and maintain correct error handling in the code that requires it, without filling the elements vertically and horizontally using nested try / catch blocks.

You can make these methods private, as they are intended for internal use only, presumably.

 private Integer getDatastoreACount() { try { DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); Key qKey = KeyFactory.createKey("qu", qURL); return (Integer) datastore.get(qKey).getProperty(kLastKnownANumber); //..etc.. more try catch blocks needed } catch (EntityNotFoundException e) { // expects an Integer return, so need to deal with this // but for simplicity I'm just simply recycling 'e' throw e; } } public void parseJSON(String jsonString) { try { JSONObject jsonObject = new JSONObject(jsonString); int aCount = jsonObject.getInt("acount"); String devTok = jsonObject.getString("dt"); String qURL = jsonObject.getString("qu"); Integer dsACount = getDatastoreACount(); //etc etc } catch (com.google.appengine.repackaged.org.json.JSONException e) { e.printStackTrace(); } } 
+2
source

You can catch several exceptions in the same attempt, for example.

 try{ xyz; }catch(NullPointerException npx){ npx.getMessage(); }catch(ArrayOutOfBoundsException ax){ ax.getMessage(); } 

In addition, by declaring the exception as throws in your method signatures, you can pass the exception to the stack.

+1
source

If you have a code block in which more than one type of exception can be thrown, you can declare two separate catch blocks:

 try { JSONObject jsonObject = new JSONObject(jsonString); int aCount = jsonObject.getInt("acount"); String devTok = jsonObject.getString("dt"); String qURL = jsonObject.getString("qu"); DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); Key qKey = KeyFactory.createKey("qu", qURL); int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber); } catch (EntityNotFoundException e) { e.printStackTrace(); } catch (com.google.appengine.repackaged.org.json.JSONException e) { e.printStackTrace(); } //..etc.. as many catch blocks as needed 

Alternatively, if you don't need the exact type of exception, you can have onyl a single catch block that catches Exception (or maybe Throwable ; I can't remember exactly what the superclass of exceptions is in Java).

Another point that I will do now is that you may not have the most modular code. Remember that code that does one thing does well for good modular code. If you find that you have a lot of nested blacks (try / catch blocks, if / else blocks, etc.), you can check if some code can be extracted into its own method. It can also make your code better when you need to handle many exceptions.

0
source

First, from a design point of view, trapping and printing exceptions is not very good. Something went wrong and your code just keeps going the same as if it did the right thing. This is usually not the case. So: perhaps your method should throw these exceptions instead of catching them. Perhaps only the caller can decide what will happen if something is wrong.

But otherwise, the only advice I can offer to clear what the code looks like syntactically is to tell you what you can write:

 try { ... } catch (...) { ... } catch (...) { ... } 

You can also catch a wider class of exceptions like Exception and just write a single catch block, but that's a bad design. In Java 7, you can catch several types of exceptions in one block.

0
source

You should use try / catch blocks if you have a way to recover from an exception, for example, if you want to check if a string is a valid integer, you can write a method (this is a chrome method, but just to show this idea):

 public boolean isInteger(String str) { try { new Integer(str); } catch(NumberFormatException e) { return false; } return true; } 

If you don’t have a way to recover from the exception, and all you do is print the stack trace, it is recommended that you add the throws method (as an eclipse hint) to the method and allow the caller to handle the exception (or throw it to the caller).

If you want to handle some exceptions and throw some others, you can also do this.

0
source

I like to block the call to the static method to keep it tidier. For example, here is my reduced call to Set Json Value.

 private static boolean setJsonValue(JSONObject j,String key,Object value) { try { if(value instanceof Integer) { // numbers are special. We want them unquoted. int valueI = (Integer)value; j.put(key,valueI); } else j.put(key,value); return true; } catch (JSONException e) { // do nothing, it turns out return false; } } 

... and then I ignore the return values ​​because I'm bad.

Somewhere or I have a similar Get method that returns null if it fails. You get the idea.

0
source

Here you have two basic code variants (which are not related to replacing method signatures)

Method1: Put everything in one try catch and you have several catch blocks, for example:

 try { JSONObject jsonObject = new JSONObject(jsonString); int aCount = jsonObject.getInt("acount"); String devTok = jsonObject.getString("dt"); String qURL = jsonObject.getString("qu"); DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); Key qKey = KeyFactory.createKey("qu", qURL); int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber); //..etc.. more try catch blocks needed } catch (EntityNotFoundException e) { e.printStackTrace(); } catch (com.google.appengine.repackaged.org.json.JSONException e) { e.printStackTrace(); } 

Method 2. Break the code into sections, each of which has one catch , for example:

 String qURL = null; try { JSONObject jsonObject = new JSONObject(jsonString); int aCount = jsonObject.getInt("acount"); String devTok = jsonObject.getString("dt"); String qURL = jsonObject.getString("qu"); } catch (EntityNotFoundException e) { e.printStackTrace(); } try { DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); Key qKey = KeyFactory.createKey("qu", qURL); int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber); } catch (EntityNotFoundException e) { e.printStackTrace(); } 

Method 2 is recommended because it makes it clear which lines throw these exceptions and usually segment the code into natural processing units.

0
source

If you just do something like this:

 try { do smth try { do smth more ... } catch (Exception1 e1) {reaction to e1} } catch (Exception2 e2) {reaction to e2} 

You can do it all in one try block:

 try { do smth do smth more ... } catch (Exception1 e1) {reaction to e1} catch (Exception2 e2) {reaction to e2} 

You can also break this into a single catch block if you just throw an exception:

 try { do smth do smth more ... } catch (Exception e) {e.printStackTrace();} 

But this is not so if you want to do something else, even if e1 selected, for example:

 try { do smth try { do smth more ... } catch (Exception1 e1) {reaction to e1} do smth even if e1 was thrown } catch (Exception2 e2) {reaction to e2} 

The last example cannot be written shorter.

0
source

Source: https://habr.com/ru/post/892080/


All Articles