Search code examples
javascriptgoogle-chromefetch-api

Javascript fetch exception causes dead stop


I have the following code:

        function makeid(length) {
            var result = '';
            var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
            var charactersLength = characters.length;
            for ( var i = 0; i < length; i++ ) {
                result += characters.charAt(Math.floor(Math.random() * 
            charactersLength));
            };
            return result;
        };

        var instance = "{{ user }}" + makeid(16);
        var checksum = "First Request Not recieved";
        console.log(instance);
        function downloadPlay(){
            console.log("\ndownloadPlay - Begin\n")
            try{
                fetch("/file?instance=" + instance + "&checksum=" + checksum)
                .then(function(resp) {
                    resp.headers.forEach(
                        function(val, key) {
                            // console.log("key, val: " + key + ", " + val); 
                            if(key == "checksum"){
                                console.log("checksum: " + val); 
                                checksum = val;
                            };
                        }
                    );
                }
            )
            .then(file => {
                var audio = new Audio("/file?instance=" + instance + "&checksum=" + checksum);
                console.log("Done");
                audio.addEventListener('ended', (event) => {
                    delete audio;
                    downloadPlay();
                });
                audio.play();
                }
            )
            } catch (error) {
                console.log("Something went wrong, Retrying: " + error);
            }
            console.log("downloadPlay - Complete\n")
        };
        downloadPlay();

This works perfectly when the promise succeeds. However when it fails(such as when the client device switches networks, i.e. wifi to data or just different access points on the same wifi network) it stops dead and never resumes no matter how many while loops, extra recursion points or try and catch statements I use. The best I could do so far is get it to play ever increasing numbers of the audio mostly in sync with each other and I just dont understand why. It seems I have a general lack of understanding of how this promise thing actually functions, but no matter how many tutorials I read/watch my lack of understanding seems to remain unchanged.

Heres the code that somewhat worked if that helps:

        function makeid(length) {
            var result = '';
            var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
            var charactersLength = characters.length;
            for ( var i = 0; i < length; i++ ) {
                result += characters.charAt(Math.floor(Math.random() * 
            charactersLength));
            };
            return result;
        };

        var instance = "{{ user }}" + makeid(16);
        var checksum = "First Request Not recieved";
        console.log(instance);
        function downloadPlay(){
            console.log("\ndownloadPlay - Begin\n")
            try{
                console.log('fetching')
                fetch("/file?instance=" + instance + "&checksum=" + checksum)
                .then(function(resp) {
                    resp.headers.forEach(
                        function(val, key) {
                            // console.log("key, val: " + key + ", " + val); 
                            if(key == "checksum"){
                                console.log("checksum: " + val); 
                                checksum = val;
                            };
                        }
                    );
                }
            ).catch(function(error) {
                console.log('request failed', error)
                console.log('retrying')
                downloadPlay();
                return;
            })
            .then(file => {
                var audio = new Audio("/file?instance=" + instance + "&checksum=" + checksum);
                console.log("Done");
                audio.addEventListener('ended', (event) => {
                    delete audio;
                    downloadPlay();
                });
                audio.play();
                }
            )
            } catch (error) {
                console.log("Something went wrong, Retrying: " + error);
            }
            console.log("downloadPlay - Complete\n")
        };
        downloadPlay();

Any solution or very simple explanation on what im doing wrong would be much appreciated Thanks in advance :)


Solution

  • You can do something like this

    Just remove the comment and use your original fetching function

    You can't use try catch with promises unless you use async await

    const fakeChecking = Promise.resolve({headers: {checksum: 'aaaa'}})
    const errorChecking = Promise.reject('error')
    
    function downloadPlay(fetching) {
      console.log("\ndownloadPlay - Begin\n")
    
      console.log('fetching')
      fetching
        .then((resp) =>  resp.headers.checksum)
        .then(checksum  => {
          /*var audio = new Audio("/file?instance=" + instance + "&checksum=" + checksum);
          console.log("Done");
          /*audio.addEventListener('ended', (event) => {
            delete audio;
            downloadPlay();
            console.log("downloadPlay - Complete\n")
          });
          audio.play();*/
          console.log("downloadPlay - Complete\n")
        })
        .catch(function(error) {
          console.log('request failed', error)
          console.log('retrying')
          downloadPlay(fakeChecking);
        })
       
    };
    
    downloadPlay(errorChecking);