Unavailable script breaks the whole chain
toxcct opened this issue · 5 comments
Hello,
First of all, I think this is not really a bug, but I don't see a real appropriate place to ask, so please pardon me already if i'm doing wrong, in which case you may close/move it.
Anyway, here my issue.
I'm using LABjs to dynamically load modules scripts.
I usually write my modules in a way that the site should be supposed to run in a 'lesser mode' (at least for some of them) if any of them is not properly loaded.
To test this, I simply made one of the modules unavailable on the server. And my surprise was that when one of the scripts expected was not loaded (here, due to an HTTP/404), then it breaks down the whole chain (in the sens that no other script is loaded, and no other .wait() function is executed either, letting unexecuted the scripts passed to the .wait() function as well).
I was then wondering if there could be some kind of ways to tell that a script is required or only 'to be loaded' ; a bit like the php function include() and require().
In the require() case, it could be accepted to have the chain broken if a mandatory script is not loaded. However, in the include() case, then i'm expecting the script to be found and loaded, but if it's not, then it's ok anyway, my site can still work without...
I was also thinking of providing a callback function as a parameter to the .setOption() or .setGlobalDefaults() to handle smoothy the case where we could have an exception thrown that LABjs cannot handle itself, but that the application loading could.
What do you think ?
If anyone reading this is also willing to jump in the topic, i'm interrested to share your thoughts.
Thanks and regards,
toxcct
@toxcct
You are correct in your observation that some types of "script failed to load" will in fact cause a chain to break. Other types will let it keep going (though the lack of dependency can cause JS errors).
However, this is not controlled by LABjs at all, thus it's not something I can fix. Browsers are inconsistent on how they handle the load
event. Some of them will fire the load event even in a 404 condition (which, if you think about it, is totally wrong), and others (most, thankfully) won't. On the flip side, these same inconsistencies exist with the error
event. You'd think that either the load
or the error
event should always fire. Unfortunately, that's not the case. Sometimes neither fires, sometimes both fire (bizarrest of all!).
Bottom line: LABjs can't really rely on either event, so it just assumes that load
will definitely fire in a successful loading case, and it basically punts on handling the "didn't correctly load" case. So, unfortunately, I can't do anything about the fact that the chain stops when one fails to load.
BTW: others in the past have addressed "fallback" behavior like this (ie, what to do when something fails to load) by setting up a timeout and just making some assumptions about a failed load if a certain amount of time goes by. I don't recommend that, per se, but that's how some people have gotten around this.
@getify
Well for the load event not always sent regarding the browser, that can be an endless philosophical discussion. For my part, I wouldn't mind if the load event is fired if the page requested in the address bar is retrieved but not all the relative contents, like images (but you got me unprepared on this question, and never really thought about that anyway :-) ).
For the error event, I was more thinking of a way to get the status of the XHR object. This way, you could have a first serious check on how a script was retrieved (if the status is "OK", then you can proceed, but if the status is "Not found", then the chain could fall back in an error callback if provided, or continue with the default behavior if not).
I'm especially thinking of how jQuery is allowing to retrieve content and to handle the success and error cases...
I've barelly seen how @jasonhinkle forked LABjs to add his own handling, but i'm not sure this is what i'm after though.
LABjs doesn't use XHR except in some rare fallback cases for old browsers. So we're reliant on the events that the <script>
element can give. That's the unreliability I was talking about before.
One primary design goal of LABjs is to only expose as functionality in the API that which can actually be reliably implemented cross browser. If you can't do it reliably, I don't think you should make a "maybe works" kind of function in an API, as its exposing you to more problems and devs' blame.
Thanks for the mention ;-) Blast from the past, Kyle and I have had this discussion a few times already!
I think we both agree that you shouldn't try to recover from a loading error, but we just have a different philosophy as to what should happen. Kyle is protecting you from yourself. My fork, which is really just a very minor tweak, gives you enough rope to hang yourself. I don't encourage anybody to try to recover from loading errors, though. From our discussions that's why I understand Kyle doesn't feel it belongs in the main branch - because it would encourage people to do exactly that.
I use it only so that my app will crash in a more visible way when something goes wrong. At the end of the day it just making debugging a little easier (for me anyway). It doesn't make an app any more robust or error-proof.
Just wanted to double-check, this loading failure being discussed here is the same thing a mixed-content (http-in-a-https) warning would trigger, right?