How to catch errors thrown by eval() properly? - javascript

I'm trying to make it easier to debug when an exception is thrown by eval().
If I simply do this:
let something = 0;
eval("something else");
Then everything would crash, and it says:
undefined: 1
something else
^^^^
SyntaxError: Unexpected token 'else'
{stacktrace}
pointing to whatever the issue was with these ^^^^, along with the stack trace etc.
However, if I put this in a try/catch like this:
try{
let something = 0;
eval("something else");
}catch(e){
console.log(e);
}
Then it prints out:
SyntaxError: Unexpected token 'else'
{stacktrace}
without the nice arrows pointing to the problem in the original evaluated string.
How can I catch the error and make it output the exact same thing as it does without catching it? Is it possible?

Related

How to use a user's submitted code, and get its errors to have relevant info?

So I'm creating a mod for the singleplayer browser game Cookie Clicker. In my mod I allow the user to insert in their own code to do their own special things to interact with my mod's main function.
However, when the user codes on my custom editor, I want to "test" their code before they save to make sure no errors happen, and if they do, display a error message with what they did and where they did it. Getting the error is easy with a try/catch. But I noticed the error message is:
SynaxError: missing ) after argument list
at new Function (<anonymous>)
at HTMLAnchorElement.save.onclick (chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/userscript.html?name=Building%2520Sorter.user.js&id=18320655-b018-42e2-8fa5-7fb0cc8d2d70:578:24)
Which isn't helpful for me at all. The most I could salvage from this is the first line. However, that doesn't tell the user at all where the error is located in their code.
the 578:24 that points to the supposed error is:
try{
//code.value is a STRING of the user's code
let func = new Function(code.value);//<-- error points here in my source code.
func.call(null, [[0, 1, 2], Game]);
save.classList.remove('ModBuildingSorter_unsaved');
}
catch(e){
console.dir(e);
}
What I would like to happen is when the user sumbits:
return function(array){
return array.sort(function(building1,building2){
return building1.price - building2.price;
};// missing array.sort closing parenthesis
}
get's ran, I can get a syntax error telling me it's on line 4
Is there a way I can do this? Make the user's code act kinda like it's own file and try running it so I can find out which row & column the error is located?
You could, in theory, run the function from an eval()
i.e.:
try {
let a = "function test(o){console.lo(o)}test('hello');" // Minified function
eval(a)
} catch (e) {
console.log(e)
}
Here is the unminified function for example purposes:
function test(o)
{
console.lo(o) // <-- Error
}
test('hello');
and this returns the error correctly, which is
TypeError: console.lo is not a function
at test (eval at <anonymous> (D:\StackOverflowSandbox\index.js:3:5), <anonymous>:1:26)
Hope I've helped.

How to pass native ReferenceError object stack to console in a JavaScript try catch?

In JavaScript, when using a try catch, how can I get the native Chrome ReferenceError object to the console as it would normally be logged? I can get close by using the Error object's stack property, but it logs the errors differently:
try {
bet you can't run this you dumb computer;
}
catch(error) {
console.log(error.stack);
}
When running the above, I get the following in the console:
While this is slightly helpful, clicking on the line number takes me to the console.log(error.stack) line in the code, not the error.
Without the try catch, the error looks like this:
and clicking on the line number will take me exactly to where the original error occurred. So how can I get this native Chrome error object to pass to the catch and then log to the console so that I can navigate to the original error and line that was thrown as it would normally be without the try catch in place?
I believe it'll work with the error method from the console object:
try {
bet you can not run this you dumb computer;
}
catch(error) {
console.error(error);
}
Hope this helps!

JavaScript: Try/Catch - what am I doing wrong here?

I am wrapping my code into try/catch blocks and I decided to test it out to see how it works.
Below is a simple snippet of code that will generate a Syntax Error - trigge rHandler
try{
$(document).trigge rHandler('fbload');
}catch(e){
alert(e);
}
However I'm not getting the alert! Instead the error is logged in the console as an Unhandled Syntax Error. I was expecting that any error that is generated inside the Try block will automatically be passed down into the Catch section where I can do anything I want with it? Why does this not appear to be working?
try..catch will catch exceptions which occur at runtime. But Syntax errors occur during parsing time itself. So, when the code
$(document).trigge rHandler('fbload');
is encountered, JavaScript tries to parse the expression. But it couldn't. So it is clueless and fails immediately with SyntaxError and that is why it is not caught by the except block.

try and catch javascript unexpected identifier

i'm tryin to identify the error i get in a javascrip function in my webpage, so i added
function guardarMisDatos() throws Exception {
try{
...
} catch (Exception e){
alert("error: ", e);
}
but when i open the page, the chrome web console gives me error at
function guardarMisDatos() throws Exception {
and the error type is "Uncaught syntaxerror: unexpected identifier"
where is the error? is it a correct way to check way the function is not fired on the first click?
It is JavaScript not Java. Lose the throws Exception!
Your code looks a lot like Java, not javaScript. The syntax for try/catch in javaScript goes like this:
try {
// do stuff
} catch (e) {
// something bad happened
}
Notice there is no throws and no type on e (since javascript is loosely typed)
Remove "throws Exception" and the catch reference to "Exception". To know what kind of exception it is, look at the e.name property, it'll be one of six things:
EvalError - An error in the eval() function has occurred.
RangeError - ut of range number value has occurred.
ReferenceError - An illegal reference has occurred.
SyntaxError - A syntax error within code inside the eval() function has occurred. All other syntax errors are not caught by try/catch/finally, and will trigger the default browser error message associated with the error. To catch actual syntax errors, you may use the onerror event.
TypeError - An error in the expected variable type has occurred.
URIError - An error when encoding or decoding the URI has occurred (ie: when calling encodeURI()).
These aren't constants, they're the actual string, as in if (e.name.toString()=="TypeError") There are a lot of other good things on the error object too, read more at http://www.javascriptkit.com/javatutors/trycatch2.shtml
Remove the throws Exception from your function definition. You do not need this in JavaScript. Besides that, why would your function ever throw an exception - you already catch it!

How to create, design and throw built-in Error objects

UPDATE
[Rewriting question to focus on the problem I am trying to understand.]
Is there a means in JavaScript to throw Exceptions that notify the line number where the problem occurs? Similar to C#'s debugger, if an error is thrown on line 50 then I will be taken to line 50.
For example, according to MDN EvalError represents an error with eval(). So, let's say I have a function that uses eval(). I want to use a specific error that is representative of the problem at hand, EvalError:
//As written here the error implies there is a problem on this line. See Firebug console window
var evalErra = new EvalError('required element missing from evaluation');
var stringFunc = "a=2;y=3;document.write(x*y);";
EvalString(stringFunc);
function EvalString(stringObject) {
//Some arbitrary check, for arguments sake let's say checking for 'x' makes this eval() valid.
if(stringObject.indexOf('x') !== -1) {
throw evalErra;
//throw 'required element missing from evaluation';//This way offers no line number
}
eval(stringFunc);//The problem really lies in the context of this function.
}
If I'm going about this all wrong, then please tell me how I should approach these kinds of issues.
When you throw an error, execution of the current code will stop and JS will work its way back up the execution tree until it finds a catch () which handles the particular type of error being thrown, or gets all the way up to the top of the tree, causing an "unhandled exception" error: You threw an error, and nothing caught it, and now someone's window got broken.
try {
if (true) {
throw 'yup'
}
} catch (e) { // catches all errors
... handle the error
}
When doing error handling you want to do the following
throw new Error("message");
Then if you ever handle this error look at err.stack (firefox/opera/chrome) or err.line (Safari) or err.IE_Y_U_NO_SHOW_ME_ERROR_LINE_NUMBER (IE) to find the line number.
If you want you can subclass Error.

Categories

Resources