Java exception handling in unclassified tasks (pattern / good practice)

There is some task that should be performed in parallel (for example, opening a file, reading, writing and closing, there is an order on this ...)

But ... Some task is more like a shopping list, I mean that they may have the desired order, but this is not necessary ... an example when exchanging or downloading independent drivers, etc.

For such tasks, I would like to know the best practices or java templates for managing exceptions.

Simple java way:

getUFO { try { loadSoundDriver(); loadUsbDriver(); loadAlienDetectorDriver(); loadKeyboardDriver(); } catch (loadSoundDriverFailed) { doSomethingA; } catch (loadUsbDriverFailed) { doSomethingB; } catch (loadAlienDetectorDriverFailed) { doSomethingC; } catch (loadKeyboardDriverFailed) { doSomethingD; } } 

But what about an exception in one of the actions, but try with the following:

I thought about it, but it seems not very useful to use exceptions. I don’t know if this works, it doesn’t matter, it's really terrible !!

 getUFO { Exception ex=null; try { try{ loadSoundDriver(); }catch (Exception e) { ex=e; } try{ loadUsbDriver(); }catch (Exception e) { ex=e; } try{ loadAlienDetectorDriver(); }catch (Exception e) { ex=e; } try{ loadKeyboardDriver() }catch (Exception e) { ex=e; } if(ex!=null) { throw ex; } } catch (loadSoundDriverFailed) { doSomethingA; } catch (loadUsbDriverFailed) { doSomethingB; } catch (loadAlienDetectorDriverFailed) { doSomethingC; } catch (loadKeyboardDriverFailed) { doSomethingD; } } 

It seems not difficult to find the best practice for this. I'm still not

thanks for any advice

+4
source share
4 answers

Consider performing around an idiom .

Another option (which is not so different, it just separates them more) is to perform each task in a separate thread.

Edit:

Here is what I mean:

 public interface LoadableDriver { public String getName(); public void loadDriver() throws DriverException; public void onError(Throwable e); } public class DriverLoader { private Map<String, Exception> errors = new HashMap<String, Exception>(); public void load(LoadableDriver driver) { try { driver.loadDriver(); } catch (DriverException e) { errors.put(driver.getName(), e); driver.onError(e); } } public Map<String, Exception> getErrors() { return errors; } } public class Main { public void loadDrivers() { DriverLoader loader = new DriverLoader(); loader.loadDriver(new LoadableDriver(){ public String getName() { return "SoundDriver"; } public void loadDriver() { loadSoundDriver(); } public void onError(Throwable e) { doSomethingA(); } }); //etc. Or in the alternative make a real class that implements the interface for each driver. Map<String, Exception> errors = loader.getErrors(); //react to any specific drivers that were not loaded and try again. } } 

Edit: this is what a pure Java version would ultimately look like if you implemented drivers as classes (this is what the Java OO paradigm expects IMHO here). The Main.loadDrivers () method would change as follows:

  public void loadDrivers(LoadableDriver... drivers) { DriverLoader loader = ... for(LoadableDriver driver : drivers) { loader.load(driver); } //retry code if you want. Set<LoadableDriver> failures = loader.getErrors(); if(failures.size() > 0 && tries++ > MAX_TRIES) { //log retrying and then: loadDrivers(drivers.toArray(new LoadableDriver[0])); } } 

Of course, I no longer use the map because the objects will be self-sufficient (you can also get rid of the getName () method, but you probably have to override toString ()), so the errors just return in order to try again. You can make the retry code even easier if each driver is responsible for how often it should retry.

Java won't look as good as a well-made C ++ template, but it's the choice of a Java language design - it prefers simplicity over complex language features that can make code more difficult over time if it isn't done properly.

+5
source

Try the following:

 protected void loadDrivers() { loadSoundDriver(); loadUsbDriver(); loadAlienDetectorDriver(); loadKeyboardDriver(); } 

Then:

 protected void loadSoundDriver() { try { // original code ... } catch( Exception e ) { soundDriverFailed( e ); } } protected void soundDriverFailed( Exception e ) { log( e ); } 

This gives subclasses the ability to change behavior. For example, a subclass may implement loading each driver into a separate thread. The main class does not need to care about how the drivers load, and whether users of the main class should not.

+3
source

IMO, for your case, if the exception is "ignorant", it is best if the "loadSoundDriver" method catches the exception and simply returns an error.

Then, in the function that loads the material, you can record all the errors and decide at the end of the sequence what to do with them. [edit] Something like this:

 // init MyError soundErr = loadSoundDriver(); MyError otherErr = loadOtherDriver(); if(soundErr!=null || otherErr !=null){ // handle the error(s) } 
+1
source

Just combine each loading operation with your own try / catch block.

 try { loadSoundDriver(); } catch (loadSoundDriverFailed) { doSomethingA; } try { loadUsbDriver(); } catch (loadUsbDriverFailed) { doSomethingB; } // ... 

Thus, you can handle each exception yourself and continue processing other operations.

0
source

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


All Articles