No internet connection
  1. Home
  2. How to

Error handling of existing function

By Alex Oldroyd @Alex_Oldroyd8
    2022-08-04 14:50:14.254Z

    Hi @chrscheuer

    I've read through the information and reading other threads, i can see how to handle errors within a function's code but it's not clear how to handle errors when calling a function.

    I have a situation where the function is quite long and convoluted. There are a few errors that seem to get thrown up randomly. Running the script again often solves the issues. Ideally I'd like to be able to call the function as many times as needed until there are no errors. It would also be ideal if the error could be logged in console for inspection.

    Something that looks like this would be ideal:

    function keepAttemptingToBounceStem() {
        while (true) {
            if (bounceStem().success) {
                break;
            }
        }
    }
    

    Thanks!

    Solved in post #5, click to view
    • 10 replies
    1. You could use a try/catch block for this. Don't add the ".success" here, that's only available for SF action calls.

      The try/catch block method is discussed in the article I referred to - but it's a normal Javascript structure so you could find it in any Javascript documentation :)

      https://help.soundflow.org/en/articles/5638002-error-handling-in-soundflow-scripts

      1. Example:

        function keepAttemptingToBounceStem() {
            while (true) {
                try {
                    bounceStem();
        
                    //Success, so break out of the loop
                    break;
                } catch (err) {
                    //An error occurred. Wait for some time, then try again (continuing the while loop)
                    sf.wait({ intervalMs: 2000 });
                }
            }
        }
        
        1. Note that I'd generally recommend using a for loop instead of a while loop, to limit the number of retries to a set amount instead of it being infinite.

          1. Here I've refactored the retry algorithm out into a separate function so you can reuse the logic :)

            function retry({action, intervalMs, numberOfTries}) {
                for(var i=0; i<numberOfTries; i++) {
                    try {
                        action();
            
                        //Success, so break out of the loop
                        break;
                    } catch (err) {
                        if (i === numberOfTries - 1) {
                            throw `We tried ${numberOfTries} times, but failed every time`;
                        }
            
                        //An error occurred. Wait for some time, then try again (continuing the while loop)
                        sf.wait({ intervalMs: intervalMs });
                    }
                }
            }
            
            retry({
                action: () => bounceStem(),
                intervalMs: 2000,
                numberOfTries: 10,
            });
            
            Reply3 LikesSolution
            1. AAlex Oldroyd @Alex_Oldroyd8
                2022-08-07 11:12:00.303Z

                Amazing!! Thanks, @chrscheuer !! This is exactly what I was after!!

                1. In reply tochrscheuer:
                  TTristan Hoogland @Tristan
                    2022-10-15 01:50:26.284Z

                    Heya @chrscheuer

                    Thanks for this script! I've been using it as a means to try circumvent "filename already exists" and add an integer when doing bounces in protools. My only issue is that for whatever reason, it's only retrying the process once for me. I.e. Bounce Name_10, retry _11, retry_12 and stops there. Adjusting the numberOfTries doesn't seem to change anything on my end.

                    If I copy and paste the final 5 lines of that little retry section (i.e. below), it attempts it several more times (depending how many times I've copied and pasted that little snippet in a row).

                    
                    sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first.buttons.whoseTitle.is("Bounce").first.elementClick();
                    
                    function bounceAlreadyExists() {
                    var alreadyExistsConfirmDlg = sf.ui.proTools.confirmationDialog;
                        if (alreadyExistsConfirmDlg.exists) {
                            alreadyExistsConfirmDlg.elementWaitFor({ waitType: 'Appear' });
                    
                            alreadyExistsConfirmDlg.buttons.whoseTitle.is("No").first.elementClick();
                    
                            alreadyExistsConfirmDlg.elementWaitFor({ waitType: 'Disappear' });
                    
                        //Find the first text field
                        var existingFileName = sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first.textFields.first;
                    
                        //Get the current Name
                        var currentName = existingFileName.value.value;
                    
                        //Create a new name (get the name and suffixed number - if your session name was 'My Session 42' then save 'My Session ' in grps[1] and '42' in grps[2])
                        var grps = currentName.match(/^(.+?)(\d+)$/);
                    
                        //Construct a new name based on the prefix and the number (+1), followed by the '.ptx' suffix. If there was no number, just add '.01'
                        var newNumber = !grps || grps.length === 0 || isNaN(Number(grps[2])) ? ' 01' : ((Number(grps[2]) + 1) + '').padStart(2, '0');
                        var newName = (grps ? grps[1] : (currentName)) + newNumber;
                    
                        //Set the value of the textField
                        existingFileName.elementSetTextFieldWithAreaValue({ value: newName });
                    
                        sf.ui.proTools.windows.whoseTitle.is("Bounce Mix").first.buttons.whoseTitle.is("Bounce").first.elementClick();
                     
                        }
                    
                    }
                    
                    bounceAlreadyExists();
                    
                    function retry({action, intervalMs, numberOfTries}) {
                        for(var i=0; i<numberOfTries; i++) {
                            try {
                                action();
                    
                                //Success, so break out of the loop
                                break;
                            } catch (err) {
                                if (i === numberOfTries - 1) {
                                    throw `We tried ${numberOfTries} times, but failed every time`;
                                }
                    
                                //An error occurred. Wait for some time, then try again (continuing the while loop)
                                sf.wait({ intervalMs: intervalMs });
                            }
                        }
                    }
                    
                    retry({
                        action: () => bounceAlreadyExists(),
                        intervalMs: 2000,
                        numberOfTries: 10,
                    });
                    
                    retry({
                        action: () => bounceAlreadyExists(),
                        intervalMs: 2000,
                        numberOfTries: 10,
                    });
                    
                    retry({
                        action: () => bounceAlreadyExists(),
                        intervalMs: 2000,
                        numberOfTries: 10,
                    });
                    
                    retry({
                        action: () => bounceAlreadyExists(),
                        intervalMs: 2000,
                        numberOfTries: 10,
                    });
                    
                    retry({
                        action: () => bounceAlreadyExists(),
                        intervalMs: 2000,
                        numberOfTries: 10,
                    });
                    
                    retry({
                        action: () => bounceAlreadyExists(),
                        intervalMs: 2000,
                        numberOfTries: 10,
                    });
                    
                    1. The retry function only retries if there's an exception caught. Were you trying to get this to just double check the filename so it won't overwrite with an invalid name?

                      For that, it would be better to read the contents of the audio files folder and come up with a unique name instead.

                      1. TTristan Hoogland @Tristan
                          2022-10-15 14:28:26.287Z

                          Thanks @chrscheuer !

                          That’s exactly what I’m trying to do. The user is prompted and enters a mix name, stored as a globalState variable and so entering the same bounce name, while unlikely is possible. I’m trying to get it so in the event protools reports back a duplicate/overwrite prompt, it re-reads the textfield value and increments the file name.

                          Your suggestion does make more sense and would incur a lot less issues with multiple prompts so I’ll try that. If you have any immediate scripts handy for that that you could share that’d be great! Otherwise I’ll dig around later and see what I can accomplish on my own.

                          1. Use sf.file.exists(( path: ' ... ' }).exists to check if a file exists :)

                            1. In reply tochrscheuer:
                              TTristan Hoogland @Tristan
                                2022-10-17 17:52:19.692Z

                                wow and after hours of scratching my head, then posting this, 2 minutes later I figured it out. Thanks!