POSTing to server if external file takes too long to load
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

What I want: I want the JS to notify my server if an external dependency took over x seconds to load.

I use Airbrake.io to report Javascript errors for Bountify. Airbrake is mostly reliable, but every now and then I get 'Waiting for api.airbrake.io..' for an extended period of time (30+ seconds). The result is that the page appears to hang.

I want the Javascript to detect how long it takes to load an external file (it should work on any external script). If it takes over x seconds, it should POST to https://bountify.co/airbrake_fail. You can assume the file will finish loading, but I'll double the bounty if you can make it POST at exactly x seconds, even as the file continues to load.

I'll also double the bounty if you can find a way to cut off the download if it takes over x seconds.

I'm aware I can set up my own Errbit server, just host the JS file myself, change services, move the link out of the head section of the page, and probably other things, but the solution above seems to be the most fun.

For the https://bountify.co/airbrake_fail, what would the POST parameters be?
alex 9 years ago
You could send the time in ms that the timeout was set to. Thanks!
bevan 9 years ago
awarded to alex
Tags
javascript

Crowdsource coding tasks.

1 Solution

Winning solution

To do this I believe you would have to load the JS through another function to track it. In your case for AirBrake, I would replace this snippet

<script type="text/javascript">
//<![CDATA[

  (function(){
    var notifierJsScheme = (("https:" == document.location.protocol) ? "https://" : "http://");
    document.write(unescape("%3Cscript src='" + notifierJsScheme + "api.airbrake.io/javascripts/notifier.js' type='text/javascript'%3E%3C/script%3E"));
  })();

//]]>
</script>

with this

<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
    var start = new Date();

    // Load the JS
        var docHead = document.getElementsByTagName('head')[0];
        var airbrake = document.createElement('script');
        airbrake.type = 'text/javascript';
        airbrake.src = "https://api.airbrake.io/javascripts/notifier.js";
        airbrake.onload = jsStatus('airbrake')
        airbrake.onreadystatechange = function() {
            if(this.readyState == 'complete') {
                jsStatus('airbrake');
            }
        }
        docHead.appendChild(airbrake);

    // Check the Time
    var check = window.setInterval(function(){
        var elapsed = new Date() - start;
        if(elapsed > timeOut) {
            jsStatus('airbrake', 'loading');
        }
    }, 500); // POST to server that sript still loading
    function jsStatus(script, isLoading) {
        var elapsed = new Date() - start;
        if (typeof(isLoading) != "undefined"){
            // Still loading
            $.post("https://bountify.co/airbrake_fail", { "script": script, "time": elapsed });
        } else {
            // Loaded
            $.post("https://bountify.co/airbrake_fail", { "script": script, "time": elapsed, "loaded": "true" });
            window.clearInterval(check);
        }
    }
</script>

Notes

Some of this code was based off this blog post by Ed Eliot and I'm not completely sure this works because I don't use airbrake and/or have any scripts to test it with.

Thanks @alex, this is great. Probably will also host the notifier myself.
bevan 9 years ago