Can syntax errors be caught in JavaScript? - javascript

MDN states:
A SyntaxError is thrown when the JavaScript engine encounters tokens or token order that does not conform to the syntax of the language when parsing code.
But if there's a syntax error, how could the program even run in the first place?
How can JavaScript syntax errors even be caught?

You cannot use try-catch blocks to handle syntax errors as they are thrown while the code is being parsed and not while it's running.
However you can use window.onerror and figure out that there's an error. You must ensure that the onerror function is defined in a separate script tag and not in the tag in which the error may be present!
Eg:
This will not work, because the script is yet to start running when the error is thrown:
<script>
window.onerror = function (e) {
console.log('Error: ', e);
};
console.log('a'');
</script>
This will work:
<script>
window.onerror = function (e) {
console.log('Error: ', e);
};
</script>
<script>
console.log('a'');
</script>
jsfiddle demo

In the JS world, SyntaxError CAN be a runtime exception. This can arise, for instance, when trying to parse a JSON response that isn't JSON format. The server can send back lots of types of responses, so if you send a HTML body response to your request that's expecting JSON in the body, you're going to get a SyntaxError thrown in the JS. In such a case, you would get an error message that looks something like this: SyntaxError: JSON Parse error: Unrecognized token '<'.
But there are other runtime SyntaxErrors you could get as well. Mozilla has a list of some here: SyntaxErrors for JSON parsing
You may want to catch these in your code. You can do so with a generic try/catch block like this:
try {
JSON.parse('<html></html>');
} catch (e) {
console.log("I catch & handle all errors the same way.");
}
OR you can look for the SyntaxError specifically:
try {
JSON.parse('<html></html>');
} catch (e) {
if (e instanceof SyntaxError) {
console.log("I caught a pesky SyntaxError! I'll handle it specifically here.");
} else {
console.log("I caught an error, but it wasn't a SyntaxError. I handle all non-SyntaxErrors here.");
}
}
Mozilla has even more info on JS errors and handling them.

It's runtime errors that can be caught with try-catch, not syntax errors (if you eval your code you can handle syntax errors in the evaled code but that's just weird).
I'd recommend you read these:
https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Statements#try...catch_Statement
https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Statements#Exception_Handling_Statements

You can catch programmer-generated and runtime exceptions but you cannot catch JavaScript syntax errors, though you may handle them in some browsers using window.onerror.
This is taken from the book JavaScript- The Complete Reference by Thomas-Powell which I like very much. You can refer to the code examples in that book.

You specifically cannot catch parser-generated SyntaxErrors since they are thrown by the parser, which has no idea what try/catch blocks do. More info on that - Learning how programming languages work
There is a way to catch SyntaxErrors that are generated during code execution. This method is slow, and I would not recommend it. You can catch SyntaxErrors using eval().
var code = `function() {
doSomething()
somethingElse()
var x = 5 + 5
// No ending curly brace` // The code to be run using eval
try {
eval(code) // Try evaluating the code
} catch (e) {
if (e.name !== 'SyntaxError') throw e // Throw the error if it is not a SyntaxError
console.log('A SyntaxError has been caught\n\nDetails:\n' + e) // It is a SyntaxError
}
Alternatively, you could use new Function(), which is up to 93% faster - https://jsben.ch/1HLQ1
var code = `function() {
doSomething()
somethingElse()
var x = 5 + 5
// No ending curly brace` // The code to be run using eval
try {
new Function([], code) // Try evaluating the code
} catch (e) {
if (e.name !== 'SyntaxError') throw e // Throw the error if it is not a SyntaxError
console.log('A SyntaxError has been caught\n\nDetails:\n' + e) // It is a SyntaxError
}

Related

A java application with J2V8 crashes when an exception happened in a some deferred section (e.g. setTimeout or process.nextTick)

I use amazing J2V8 java library which allows execute any Javascript code in your Java application furthermore it can integrates a nodeJS engine.
But i have encountered with a next issue. This code interrupts a Java application immediately after nodejs invokes a callback function of setTimeout which throw an exception although there is a try..carch block. The exception doesn't even enter into the try..catch block.
// It is an example, in real case it can be a some erorr in a code.
nodeJS = NodeJS.createNodeJS();
try {
nodeJS.getRuntime().executeVoidScript("setTimeout(function(){throw 'Error'}, 1000);");
} catch (Exception e) {
e.printStackTrace();
}
The application is interrupted with message:
undefined:1
setTimeout(function(){throw 'Error'}, 10000);
^
Error
Process finished with exit code 1
Another example shows that exceptions are not a cause of interruption of an application always and it is a 'normal' case.
nodeJS = NodeJS.createNodeJS();
try {
nodeJS.getRuntime().executeVoidScript("throw 'Error'");
} catch (Exception e) {
e.printStackTrace();
}
In this case we see the only a error message in console but the application still works.
Exception in thread "Thread-2" undefined:1: Error
throw 'Error'
^
com.eclipsesource.v8.V8ScriptExecutionException
at com.eclipsesource.v8.V8._executeScript(Native Method)
at com.eclipsesource.v8.V8.executeScript(V8.java:940)
at com.eclipsesource.v8.V8.executeScript(V8.java:595)
at com.eclipsesource.v8.V8.executeObjectScript(V8.java:625)
at com.eclipsesource.v8.V8.executeObjectScript(V8.java:608)
at org.efc.origamiapp.v8.V8Environment.run(V8Environment.java:383)
The examples above are in the try..catch blocks, and you can see trace stack below it. So the interruption is fired in Native Method (the secod example), but in the first case the JS exception just kills the Java application without any explanations in a console or in a trace log.
It looks like the error you are throwing in the javascript code is being propagated into the java environment. This is what one would expect to see given the js code you are trying to execute (throw 'Error'). What did you expect to happen? Simply catch any exceptions in java and handle appropriately - maybe by logging?
try {
nodeJS.getRuntime().executeVoidScript("throw 'Error'");
}
catch(Exception e) {
System.out.println(e.toString());
}
This is the best and correct solution.
process.on('unhandledRejection', (err) => {
console.error('Unhandled promise rejection',err);
});
process.on('uncaughtException', (err) => {
console.error('Uncaught exception',err);
});
For more information see the nodeJS documentation: Event: 'uncaughtException'
For now my workaround is this script.
let nativeSetTimeout = setTimeout;
setTimeout = function(fn, t){
let safeFn = () => {
try {
fn();
} catch(e){
console.log(e);
}
};
return nativeSetTimeout(safeFn,t);
}
let nativeNextTick = process.nextTick;
process.nextTick = function(){
let args = Array.prototype.slice.call(arguments);
let fn = args[0];
let safeFn = () => {
try {
fn.apply(null,args.slice(1));
} catch(e){
console.log(e);
}
};
return nativeNextTick(safeFn);
}
I invoke this script in a beginning of an application.
nodeJS.getRuntime().executeVoidScript(workaroundScript);

JSON.parse, already in try/catch block, still throws syntax error

parseJsonMsg(msg, jsonCallBack) {
try {
let content = JSON.parse(msg.content);
jsonCallBack(null, content);
} catch (err) {
console.log('[MSG processing ERROR]: ', err.message);
jsonCallBack(err);
}
}
This code is used to log the error whenever it is unable to parse a message.
Apart from logging, this throws syntax error if unable to parse. Why is that so? How can it be handled?
Any advice would be great
I suspect it is the method you are passing in as a parameter that is throwing the error. Make sure jsonCallBack does its own error handling. What is the error you receive?
Errors can be thrown anywhere, including inside catch blocks. If an error is thrown in a catch block it will percolate up the stack until it is either caught or the stack is exhausted and it becomes an uncaught exception.
bit of rewrite
parseJsonMsg(msg, jsonCallBack) {
var err;
var content;
try {
content = JSON.parse(msg.content);
} catch (ex) {
console.log('[MSG processing ERROR]: ', err.message);
err = ex;
}
jsonCallBack(err, content);
}
then as said above, the parse error is forwarded to the caller in jsonCallBack(err)
So it may be the caller which throws the error.
To fix your problem, you should not comment that call jsonCallBack(err) but, depending on the type of caller, bind its error handler then decide what to do.

Is there type of error in Javascript?

I would ask about java script error, is there type of error like php
or others,
example: In php we have notice, and Parse Error ..etc notice will not
be stop php execute, but parse will be stop execute php code
directly..
now is there js error like this, or what is the js classification
error .. I know we can handle error by try, catch ..,but is there
error in js was stooped script and others will not stop execute script
thank you
is there error in js was stooped script and others will not stop execute script
Not except for parsing/syntax errors, no.
JavaScript has exceptions. An exception exits the code in which it is thrown, and the code that called that, and so on until it's caught. If it isn't caught, then all currently-running functions are terminated and the error is logged to the web console.
So an exception (either one you throw explicitly or one that happens as a by-product of something you do) will either terminate all running functions (if not caught) or only terminate some code (if caught).
For example:
function foo() {
try {
bar(0);
}
catch (e) {
console.log("Caught exception");
}
}
function bar(a) {
if (a <= 0) {
throw new Error("'a' cannot be <= 0");
}
console.log("bar: a = " + a);
}
foo();
There, the code in bar following the exception is not run (we don't see "bar: a = 0") because an exception was throw, terminating bar. But foo's code continues, in the catch block, because foo caught the exception.
JavaScript is unusual in that you can throw anything, including a string, a number, etc. But if you want useful information, you usually throw Error:
throw new Error("Optional message here");
Since what you throw can be anything, you might be thinking there's a way to catch only certain things, but that's not the case. catch catches any exception that was thrown. So:
try {
throw "foo";
}
catch (e) {
}
try {
throw new Error();
}
catch (e)
}
try {
throw 42;
}
catch (e)
}
Note that those catch clauses are identical; they catch anything that was thrown. Of course, you can then inspect what you got and re-throw:
try {
// ...some code here that may throw any of several things...
}
catch (e)
if (typeof e === "string") {
// Handle it here
}
else {
throw e;
}
}
There we only handle exceptions that are strings, and not ones that are numbers, Error objects, etc.
You can create your own derived versions of Error if you like, although it's a bit more of a pain than it ought to be:
function MySpecificError(msg) {
this.message = msg;
try {
throw new Error();
}
catch (e) {
this.stack = e.stack;
}
}
MySpecificError.prototype = Object.create(Error.prototype);
MySpecificError.prototype.constructor = MySpecificError;
Then:
throw new MySpecificError("Something went wrong.");
Note that we had to fill in the code in MySpecificError to create the stack trace. (Also note that not all engines provide a stack trace, but if they do, this lets you use it.)
Some engines provide a few error types out of the box:
Error
RangeError (something was out of range)
ReferenceError (but usually that's something you'd let the engine throw)
TypeError (again)
SyntaxError (again)
Finally, it's worth noting that several things that would cause exceptions in other environments don't in JavaScript, mostly around math. For instance:
var result = 10 / 0;
In many non-JavaScript environments, that results in a runtime error (division by zero). In JavaScript, it doesn't; result gets the value Infinity.
Similarly:
var x = Number("I am not a number");
or
var x = parseInt("I am not a number", 10);
...doesn't throw a parsing error, it sets x to NaN ("not a number").
Yes. Javascript errors can have types, and there is a standard error type hierarchy. You can also write your code to "throw" things that are not error objects.
(In fact, since the catch clause in Javascript / ECMAScript does not discriminate based on the type of the exception, exception handling tends to be rather crude; i.e. "catch all errors" and then attempt to recover. Hence, to a first order, it doesn't matter what you throw.)
The ECMAScript 5.1 spec says that syntax errors are "early errors" and that they must be reported before the program is executed. An exception to this is syntax errors detected in code being run using eval. However, the spec doesn't say how early errors are to reported, or what happens afterwards. (At least, I don't think it does ...)
I believe that a common strategy for a Javascript parser/compiler/interpreter to skip to the enclosing block, and replace the affected code with code that throws an exception (e.g. SyntaxError) if it is run.
References:
http://www-archive.mozilla.org/js/language/js20-1999-02-18/error-recovery.html
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError
EcmaScript 5.1 - Errors

JavaScript Catching exception from within function or object

I encountered quite annoying problem. I can't catch errors thrown from within the functions. And to be honest - I wouldn't care much if not the fact that the same applies for throwing errors from within the JavaScript Objects.
Here's the sample code:
http://jsfiddle.net/TxsHK/1/ (you'll need firebug console to test this code)
function ViewError($CONTENT){
this.content = $CONTENT;
return this.content;
};
try{
$(document).ready(function() {
//--------------
throw ViewError('Test error');
//--------------
});//$(document).ready(function() {
}catch (e) {
if (e instanceof ViewError) {
console.info(e.message);
}
else{
console.warn(e.message);
}
}
gives an error
TypeError: e is undefined
Why? The errors thrown by functions (or objects) should be perfectly catchable. That's the whole purpose of try - catch block: to catch exceptions out of functions. At least... so it is in other languages.
Anyone can explain what's going on? And how can I catch exceptions from within the functions / objects?
Your "ViewError" function doesn't return anything. You're therefore throwing undefined. (edit — your fiddle is diffferent from the posted code - don't do that!)
The "ViewError" function is being called in a way that I don't think to be correct, given the way the code is written. I think you want throw new ViewError("Test error"); in order to make sure a new object is created.
There's another problem: you're expecting that you'll be able to catch exceptions thrown from that call to $(document).ready(), but that's not necessarily going to work. If the document isn't ready yet when that code runs, then you'll get no exceptions because the call returns immediately. The function you pass in would be called later, when the document is ready.

How javascript try...catch statement works

I am trying to test in browsermob if certain input field work or not. I am attempting to use a try...catch statement which I have never used before. I know that the form is:
try {
//some code
} catch (){
//some error code
};
What exactly is supposed to be put in the parenthesis after the catch statement?
When I try to use the statement it runs everything through the catch statement no matter if it is not an error. What am I doing wrong?
See the “try...catch statement” guide on MDN.
In short, try/catch is used to handle exceptions (which are "thrown" using the throw statement). The syntax for try/catch is:
try {
// Code
} catch (varName) { // Optional
// If exception thrown in try block,
// execute this block
} finally { // Optional
// Execute this block after
// try or after catch clause
// (i.e. this is *always* called)
}
varName is available to the scope of the catch block only. It refers to the exception object which was thrown (which could be any type of object, e.g. a String, but is usually an Error object).
The try catch statement is used to detected for exceptions/errors that are raised inside the try-block. In the catch block you can then react on this exceptional behavior and try to resolve it or get to a safe state.
You got the statement almost right:
try {
// code that may fail with error/exception
} catch (e) { // e represents the exception/error object
// react
}
Consider the following examples:
try {
var x = parseInt("xxx");
if(isNaN(x)){
throw new Error("Not a number");
}
} catch (e) { // e represents the exception/error object
alert(e);
}
try {
// some code
if(!condition){
throw new Error("Something went wrong!");
}
} catch (e) { // e represents the exception/error object
alert(e);
}
the stuff inside try {...} is what you want to execute. The stuff in catch() { ... } is what you want to execute if you get any javascript errors from anything executed in the try {...}
catch {...} only executes if there is a javascript error in the try {...} block. You can find out what the error is by doing for example this:
try {
// do something
} catch (err) {
alert(err);
}
According to ECMAScript specifications,
try {
// Code
} catch (varName) { // optional if 'finally' block is present.
if (condition) { // eg. (varName instanceof URIError)
// Condition (Type) specific error handling
}
else {
// Generic error handling
}
} finally { // Optional if 'catch' block is present.
// Execute this block after
// try or after catch clause
// (i.e. this is *always* called)
}
the code that is likely to throw an exception goes into try { }, The code to be run when an exception is thrown, comes into catch() { }. In catch() you can specify which exceptions you want to catch, and in which automatic variables to put it.
finally { } is always run, regardless whether exception was thrown or not.

Categories

Resources