解决已知异常并重新执行导致它的相同函数或代码,直到(如果)它在 JAVA 中自动解决

Resolve known exceptions and re-execute same function or code which causes it, until (if) it resolves automatically in JAVA

例如:- 一种除法

public static void divide( int a, int b) {
return a/b;  // This would throw ArithmeticException / by 0. whenever b ==0;
}

如果 b 是动态输入,假设随时间变化。当 b 不为 0 时,我想从该函数中获取一个值。在这种情况下,处理已知异常并可以解决的所有此类函数的方法将非常有益。

一个更相关和实时的例子是:-

在测试自动化中:- 如果函数单击按钮失败并出现 NoSuchElementException,那么在特定时间之前进行检查以恢复此类不需要的同步相关异常将非常有益。

在下面的代码中,您会发现以下观察结果:-

  • ArithmeticException 因为除以 0.

  • 重试逻辑将继续尝试多次重新执行相同的方法,直到它执行该方法没有失败或时间限制到期。

  • 对值进行硬编码更改以使失败的函数在特定时间后通过并重试逻辑以解决异常并在之后继续。

因此,您可以在任何地方和所有此类不需要但已知容易发生异常的方法上应用此类逻辑,这些方法由于各种原因具有自动恢复的习惯,并且您不想在声明之前检查有效时间量输出为失败。

就我而言,WebDriverExceptionNoSuchElementException 等同步问题很容易解决,因此会节省我很多时间。

    package javaTest;
    
    
    import java.lang.reflect.Method;
    import java.util.Date;
    import org.openqa.selenium.ie.InternetExplorerDriver;
    
    
    public class ExceptionHandler extends HandleException
    {
    
        public static int divide(int[] test) 
        {
            System.out.println("Calling signature 1.");
            int c = test[0]/test[1];
            System.out.println("Passed");
            return c;
        }
        
        public static int divide(int a , int b) 
        {
            System.out.println("Calling signature 2.");
            int c = a/b;
            System.out.println("Passed");
            return c;
        }
    
        
        public static void main(String[] args) throws Exception
        {
                int[] test = new int[] {2,0};
                
            try
            {
    //          divide(2,0);    // Usage below with comment Code #1
                divide(test);   // Usage below with comment Code #2
            }
            catch (Exception e)
            {
    //          exceptionRecovery(e, 40000,  "javaTest.ExceptionHandler", "divide", new Object[]{2,0} );                //Code #1
                exceptionRecovery(e, 40000,  "javaTest.ExceptionHandler", "divide", new Object[]{new int[] {2,0}} );    //Code #2
            }
        }
        
    }
    
    
    
    
    class HandleException
    {
        
        
        
        @SuppressWarnings("deprecation")
        public static void executeMyMethod(String fullClassName, String methodName, Object[] args) throws Exception
        {
            Class<?> params[]   = new Class[args.length];
                     params     = setClassTypes(args, params) ;
                     
            Class<?> cls        = Class.forName(fullClassName);
            Object _instance    = cls.newInstance();
            
                Method myMethod = cls.getDeclaredMethod(methodName, params);    
                        myMethod.invoke(_instance, args);   
                            
        }
        
        private static Class<?>[] setClassTypes(Object[] args, Class<?> params[])
        {
            for (int i = 0; i < args.length; i++)
            {
                if (args[i] instanceof Integer) 
                    params[i] = Integer.TYPE;
                else if (args[i] instanceof String) 
                    params[i] = String.class;
                else if ( args[i] instanceof InternetExplorerDriver)
                    params[i] = InternetExplorerDriver.class;
                else if (args[i] instanceof int[])
                    params[i] = int[].class;
                else 
                    System.out.println("Please ask developer to include : \'"+args[i].getClass().getSimpleName()+"\' to permitted inputs for paramters");
            }
            
            return params;
        }
    
        
        
        public static void exceptionRecovery(Exception e, int timeOut, String fullClassName, String methodName, Object[] args) throws Exception
        {
            Exception e1            = e;
            final long startTime    = System.currentTimeMillis();
            Date startDate          = new Date();
            final long waitTimer    = startTime+timeOut;
            int counter             = 0; // manually correct exception to get correct result.
            
            while(System.currentTimeMillis()<=waitTimer)
            {
                if(e1.getClass().getSimpleName().equalsIgnoreCase("ArithmeticException"))
                {
                    System.out.println("Excpetion Caught 1.");
                    try {
                        executeMyMethod(fullClassName, methodName, args);
                        String timeTaken = calcTimeDifference(startDate, new Date());
                        System.out.println("Exception Handled in: "+timeTaken+"seconds");
                        return;
                    }catch (Exception ee)   { e1 =  ee;}
                }
                else if(e1.getClass().getSimpleName().equalsIgnoreCase("InvocationTargetException"))
                {
                    System.out.println("Excpetion Caught 2.");
                    try {
                        executeMyMethod(fullClassName, methodName, args);
                        String timeTaken = calcTimeDifference(startDate, new Date());
                        System.out.println("Exception Handled in: "+timeTaken+"seconds");
                        return;
                    }catch (Exception ee)   { e1 =  ee;}
                }
                else if(e1.getClass().getSimpleName().equalsIgnoreCase("NumberFormatException"))
                {
                    System.out.println("Excpetion Caught 3.");
                    try {
                        String timeTaken = calcTimeDifference(startDate, new Date());
                        System.out.println("Exception Handled in: "+timeTaken+"seconds");
                        return;
                    }catch (Exception ee)   { e1 =  ee;}
                }
                else 
                {
                    System.out.println(e1.getClass().getSimpleName());
                        e.printStackTrace();
                        throw new Exception(e);
                }
                Thread.sleep(1000);
                
                // Manual Correction ... to be removed post validation of above code... if working as expected...
                    counter++; 
                    if(counter == 5)
                    {
    //                  args = new Object[] {1,2};  // for input type as normal
                        args = new Object[] {   new int[] {2,3} };
                    }
            }
            String timeTaken = calcTimeDifference(  startDate, new Date()   );
            System.out.println("Unable to recover in target time of :"+timeTaken+"seconds\n");
            e1.printStackTrace();
        }
        
    
    
        private static String calcTimeDifference(Date d1, Date d2)
        {
                    long diffMs = d2.getTime() - d1.getTime();
                    long diffSec = diffMs / 1000;
    //              long min = diffSec / 60;
                    long sec = diffSec % 60;
                    return sec+"";
        }
        
    }