0

Currently, when we trigger a "script" command in spring-shell prompt, it executes all the commands present in a file, even if one of them threw any exception(other than ExitRequest). I found below code in Shell.evaluate(Input), it simply returns Exception as result and stop application only if Exception is ExitRequest type. Is there a way to change this behaviour only for "script" command?

           try {
                    Object[] args = resolveArgs(method, wordsForArgs);
                    validateArgs(args, methodTarget);

                    return ReflectionUtils.invokeMethod(method, methodTarget.getBean(), args);
                }
                catch (UndeclaredThrowableException e) {
                    if (e.getCause() instanceof InterruptedException || e.getCause() instanceof ClosedByInterruptException) {
                        Thread.interrupted(); // to reset interrupted flag
                    }
                    return e.getCause();
                }
                catch (Exception e) {
                    return e;
                }
                finally {
                    Signals.unregister("INT", sh);
                }

There is no point in overriding the "script" command itself, because this code is present outside "Script.java". Currently, I have Overriden "script" command and then wrap around the Shell.run(InputProvider) invocation with a global flag EXIT_ON_ERROR. Then I created an aspect to proxy the call to any custom command. If the advice finds any Exception it throws an ExitRequest if EXIT_ON_ERROR flag is true which results in stopping the execution of rest of the commands in script file.

Code Snippet that I tried

    @ShellMethod(value = "Read and execute commands from a file.")
    public void script(File file) throws IOException {
        CustomScript.EXIT_ON_ERROR.set(true);
        Reader reader = new FileReader(file);
        try (FileInputProvider inputProvider = new FileInputProvider(reader, parser)) {
            shell.run(inputProvider);
        }
        CustomScript.EXIT_ON_ERROR.set(false);
    }
    @Around("within(com.agilone.provisioner.shell.component..*)")
    public Object allCommands(ProceedingJoinPoint joinPoint) throws Throwable{
        String commandName = ...;
        String parameters = ...;
        }
        log.info("Executing command [{} {}]", commandName, parameters);
        try{
            return joinPoint.proceed();
        }catch(RuntimeException e){
            log.error("Command [{} {}] failed", commandName,parameters, e);
            if(CustomScript.EXIT_ON_ERROR.get()){
                CustomScript.EXIT_ON_ERROR.set(false);
                throw new ExitRequest();
            }
            throw e;
        }
        
    }


RDK
  • 144
  • 1
  • 1
  • 9
  • Could you please share an MCVE : https://stackoverflow.com/help/minimal-reproducible-example ? – R.G Feb 28 '22 at 17:25
  • @R.G Please find it here. https://github.com/radhe-kishan/shell-example – RDK Feb 28 '22 at 22:29
  • Tried the code and could reproduce the usecase. I need more time to analyse this and bit tied up with work now . I hope someone might be able to help you on this soon. Something you might find interesting on this subject : https://github.com/spring-projects/spring-shell/issues/250 – R.G Mar 01 '22 at 04:20

0 Answers0