I'm using a plugin and I want to handle the errors throws. In special occasions, my script gets error and the cause is a line of code in the plugin:
...
if (!element) {
throw new Error('Container does not exist: ' + container);
}
...
Plugin failing its function is not a problem, but it stops the rest of my script (which is a problem). So I wanted to use try{}catch(e){} to avoid my script stopping.
<script src="plugin.js"></script>
<script>
//This is my script structure
var object = $('#element');
doSomething();
function doSomething(){
try {
//Here I call the plugin function...
object.pluginAction(options);
} catch(err) {
//Here's the code I want to exec if plugin function fail
console.log('Plugin error: '+err);
}
</script>
But this doesn't work. I still get the error in chrome console and no log and script crashes... How can I handle that error without editing the plugin source?
Thank you
Related
In file2.js I have:
throw new String("oops");
In file1.js I have:
document.head.appendChild(dynamically_created_file_2_script_element);
How can I catch the string thrown in file2.js?
I have tried:
try {
document.head.appendChild(dynamically_created_file_2_script_element);
}
catch(err) { ... }
to no avail. Also, the onerror event listener on dynamically_created_file_1_script_element is of no use here.
Before appending the script, you can add an error listener to the window.
The error event is fired on a Window object when a resource failed to load or couldn't be used — for example if a script has an execution error.
Inside the handler, you can check which resource resulted in the error by looking at the filename property of the event.
window.addEventListener('error', (errorEvent) => {
if (errorEvent.filename.endsWith('file2.js')) {
console.log('Saw error from file2.js:')
console.log(errorEvent.message);
}
});
document.body.appendChild(document.createElement('script')).src = './file2.js';
Note that this can only work if the script is on a live server, and on the same domain. Due to cross-origin restrictions, in other situations, the only info available will be Script error.
I can't find a way to catch the error message under firefox:
window.addEventListener("error", handleException, false);
...
function handleException(e) {
alert(e);
return false;
}
...
<script>
throw new Error('sdasd');
</script>
This enters very well the handleException method however the e parameter is an error event under firefox and I don't know how to get the associated message.
In chrome for instance, I get either the message through e.message because after the error bubbles up to not being caught, there's an automatic error fired at window level (See this fiddle: the final error is "Uncaught") that contains the original error that I raised manually.
So to have the same behaviour under firefox (if you run the fiddle under firefox you'll see that the message is "undefined") I found a workaround consisting in encapsulating an error raising function to setup a manual "last error" architecture:
function err(I_sText) {
g_lastManualError = new Error(I_sText);
throw g_lastManualError; //this variable is global so I can get the message from anywhere
}
So instead of doing throw new Error(..) I only call err(..). That works, at least for user defined exceptions, which are my biggest concern. In my handler handleException I'm consulting the global variable.
Do you know how I could do otherwise? I'm not happy with this solution.
Thank you,
S.
I modified your code a little as a demo:
function handleException(e) {
console.log(e);
alert(e);
return false;
}
window.addEventListener("error", handleException, false);
try {
throw new Error('sdasd');
}
catch (e) {
console.log(e)
}
console.log('after exception 1');
throw new Error('foo');
console.log('after exception 2');
Running this code (in Firebug) showed me this:
Error: sdasd
[Break On This Error]
Filtered chrome url chrome://firebug/content/console/commandLineExposed.js
comman...osed.js (line 175)
<System>
after exception 1
"Error: foo ` throw new Error('foo');` #14"
If you're trying to catch an error, use try {...} catch { ...}. It looks like you're just binding to an error event, so the exception you're throwing will still propagate up to window and tell the JS engine to halt. Run this code in Chrome, you'll see that you never see "after exception 2", but you will see "after exception 1".
The purpose of exceptions (created by throw) is to stop code execution unless there's code made to handle that particular exception. You can see an example on the MDN page for try-catch
Edit: it just occurred to me that you might be trying to catch a jQuery error event. If this is the case, your event binding is correct but you shouldn't be testing it with throw
Edit 2: I should've noticed this sooner, but you're trying to listen for a DOM error event with window.addEventListener. Error events will not break execution. Exceptions do.
Replace your code throw new Error('sdasd'); with this code:
var customEvent = new CustomEvent('error')
window.dispatchEvent(customEvent);
That should solve your problem. I used the MDN page on custom events as a reference.
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?
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.
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)
})
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.
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
I have a PhantomJS script that loads a local HTML file, injects some javascript files, then executes some javascript in the context of the page. The javascript that runs generates an exception, but I only get output from the console, which doesn't seem to distinguish between an error and a normal log and doesn't have file, line numbers or a stacktrace.
What I need is a way to capture or otherwise distinguish these errors. I have already tried:
Wrapping my PhantomJS script in a try-catch
Result: nothing is thrown far enough to be caught by this
Define a window.onerror function
Result: nothing happens. WebKit does not implement an onerror event on the window
I would prefer to be able to retrieve the error object itself so that I can retrieve the stacktrace.
I think there were issues with window.onerror not properly working in WebKit (https://bugs.webkit.org/show_bug.cgi?id=8519). Don't know if this has been fixed at all, and if so, if the QT WebKit version is already up-to-date.
However, you should be able to catch the exceptions thrown in your code. If you are using something like webPage.evaluate(...)to run your code, you cannot wrap the complete call in a try/catch block, since the script is evaluated in a different context and the errors will not appear in the main execution context. Insteadyou will need to catch the errors in page execution context. Unfortunately, there is no way of accessing any functions defined in the main context, we therefore have to explicitly write the wrapping code around your code to be executed.
The following is a modified example of the phantomwebintro.js file as included in the PhantomJS source. It loads an HTML page, inserts a script and then runs some code in the page context (here with a line throwing a type error). This code is wrapped with a try/catch block and will return the wrapped result or error object to the main context.
...
// Load an HTML page:
page.open("http://www.phantomjs.org", function(status) {
if (status == "success") {
// Inject some scripts:
page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
// Run your own code in the loaded page context:
var resultWrapper = page.evaluate(function() {
var wrapper = {};
try {
// Your code goes here
// ...
var x = undefined.x; // force an error
// store your return values in the wrapper
wrapper.result = 42;
} catch(error) {
wrapper.error = error;
}
return wrapper;
});
// Handle the result and possible errors:
if (resultWrapper.error) {
var error = resultWrapper.error;
console.log("An error occurred: " + error.message);
// continue handling the error
// ...
} else {
var result = resultWrapper.result;
// continue using the returned result
// ...
}
...
});
}
});
...
The solution? return true!
// Error tracking
page.onError = function(msg, trace) {
console.log('= onError()');
var msgStack = [' ERROR: ' + msg];
if (trace) {
msgStack.push(' TRACE:');
trace.forEach(function(t) {
msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function + '")' : ''));
});
}
console.log(msgStack.join('\n'));
// Consider error fully handled
return true;
};
I am facing a error in javascript....
when the javascript function calling it is not working but if i set a alert('someting'); within the function then the script is running but if i comment off the alert within the script,
is not working.
what is the solution.......
put you code in try.. catch block and check is there any exception
try
{
//Run some code here
}
catch(err)
{
//Handle errors here
alert(err);
}
Try putting your code in load event:
window.onload = function(){
// your code...
};
Or put your js code at the end of the page.
if you're running with firefox, you won't know whether error occur in this function or not.
When you include the alert your most likely giving elements on the page you are loading time to appear which are probably required for you JS to actually run.
You could try using:
window.onload = function(){
//drop some code in here
}
or you could use jquery and wrap your code into a document.ready function like this:
$(document).ready(function() {
// put all your jQuery goodness in here.
});
You will need to load the latest version of jquery onto your page if you were to you this method.