40

I am trying to load some content using require.js. If the content doesn't exist I'd like to catch the error and notify the user.

In firebug I can see two errors:

"NetworkError: 404 Not Found

...and then a few seconds later:

var e = new Error(msg + '\nhttp://requirejs.org/docs/errors.html#
Load timeout for modules: modules/messages/messages 
http://requirejs.org/docs/errors.html#timeout

My code resembles:

require([path], function(content){
  //need to catch errors as this will not be called;
});

How would one bind to requirejs events? Any idea?

6
  • 2
    I JUST ran into this... I'm going to scour the web. Race to the finish? Commented Jan 27, 2012 at 17:44
  • @Relic :) Just found this which covers it - groups.google.com/group/requirejs/browse_thread/thread/… Commented Jan 28, 2012 at 3:43
  • Doesn't fix the problem of require throwing an error that break all the other requirements... I guess that's why it's a require huh? I blame webKit, because that's the only browser's that I have load order issues with for scripts so I have to encapsulate the entire document.ready() with all my scripts at the top, not ONLY when they're being fired. luckily it's a small project and namespace but that doesn't help me in the future. --- I need a fallback... and I'm not doing a whole window capture, I'm actually trying to edit requireJS to give an option. Commented Jan 29, 2012 at 5:43
  • @Relic yeah, still working on it here. May need to ping it to check if it exists before using require. Hmmm. I'll keep you posted if I come up with something worth looking at. cheers Commented Feb 1, 2012 at 3:42
  • 1
    Okay, so here's the deal, it's a logic thing... if it's "required" to load a file to execute something, then of course it's going to error and freeze all the code in that require bucket because the file it needs isn't there. It just makes sense... I don't think it should be worked around after some thought. Keep local copies of all 'required' docs. I've learned you can't depend on third party URLs. Commented Jul 19, 2012 at 16:21

4 Answers 4

42

It is also possible to use errbacks to have customized error handling appropriate to the specific use of require. Errbacks are documented here http://requirejs.org/docs/api.html#errbacks. Basically, you can add to require a function to be called if the load fails. It comes right after the function to be called if the load is successful.

Chin's case could be handled as:

require([path], function(content){
  //need to catch errors as this will not be called;
}, function (err) {
  //display error to user
});

Here's an example that tries loading from multiple places:

require([mode_path], onload, function (err) {

    if (mode_path.indexOf("/") !== -1)
        // It is an actual path so don't try any further loading
        throw new Error("can't load mode " + mode_path);

    var path = "./modes/" + mode_path + "/" + mode_path;
    require([path], onload,
            function (err) {
        require([path + "_mode"], onload);
    });
});

In this example onload would be the function called once the required code loads, and mode_path is a string identifying the mode. What you see there is code attempting to load a mode module for an editor from 3 different locations. If mode_path is foo, it will try to load foo, then ./modes/foo/foo and then ./modes/foo/foo_mode.

The example at requirejs.org shows how one might handle a case where they want to try multiple locations for a resource they want to make available with a well-known identifier. Presumably the entire code-base in that example requires jQuery by requiring "jquery". Whatever location jQuery happens to be located at, it becomes available to the whole code-base as "jquery".

My example does not care about making the mode known to the entire code-base through a well-known identifier because in this specific case there's no good reason to do so. The onload function stores the module it gets into a variable and the rest of the code base gets it by calling a getMode() method.

Sign up to request clarification or add additional context in comments.

Comments

19

set the requirejs onError function:

requirejs.onError = function (err) {
    if (err.requireType === 'timeout') {
        // tell user
        alert("error: "+err);
    } else {
        throw err;
    }
};

If you want to setup an event you could bind to and trigger a global object. Such as:

$("body").bind("moduleFail",function(){
    alert("Handling Event")
});
requirejs.onError = function (err) {
    if (err.requireType === 'timeout') {
        $("body").trigger({type:"moduleFail",err:err})
    } else {
        throw err;
    }
};
require(["foo"],function(foo){
    alert("loaded foo" + foo)
})

Comments

8

Did you try to override the requirejs.onError like shown here?

It worked for me after setting catchError as true like this:

require.config({catchError:true});

before calling any define() or require() functions.

2 Comments

This won't fix the code... the problem is logic in the designers process if you run across this... either that, or if the file does exist you have to make sure you don't put the '.js' on the end of the file reference... gets me every time.
3

You can use the requirejs.onError function as :

requirejs.onError = function (err) {
    if (err) {
        //Reload
    } 
    else {
        throw err;
    }   
};

You can also use err.requireType to catch specific errors like timeouts

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.