How to catch exception when calling a "syscall/js" function? - javascript

I’m experiencing the use of the syscall/js GO package and I would like to find a way to catch exception on a call to a js function.
Here an example of a call throwing an exception to the browser: (You need to disable the access to the localstorage to raise the exception.)
value := js.Global().Get("window").Get("localStorage")
...
As soon as this code execute an exception is raised by the browser:
and the go/wasm code stops.
How to catch this exception to be able to resume the code and to handle the error with the UI?
regards
No clue what to try!

Probably you can do something like:
var localStorage;
try {
localStorage = window.localStorage;
} catch(e) {
// Access denied :-(
}
value := localStorage;

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!

Checking if specific console error occurred/exists with javascript

I would like to check if a certain console error has occurred using javascript, and alert() myself if it has.
The error will look like this:
00:00:34:0359 TimeEvent.COMPLETE
(anonymous function) # VM17617:1
And the algorithm will look something like this:
function checkError(console) {
if(console.error === "TimeEvent.COMPLETE") {
alert("The error is present");
}
}
I'm not very familiar with the console, and haven't gotten much further with Google research. Can somebody point me in the right direction?
I ultimately solved my question by following this blog post on taking over the console with javascript.
Here is my final code:
var original = window.console
window.console = {
error: function(){
//Gets text from error message.
errorText = arguments['0'];
if (errorText.includes('TimeEvent.COMPLETE')) {
//DO STUFF HERE
}
original.error.apply(original, arguments)
}
}
You didn't provide the whole picture about how and when the console is getting the error. If you raise the error yourself, or if you are able to catch it inside a try catch, that would be the best place to intercept those errors.
However, if you have no control about how those error are raised, you should try to intercept your console's error calls. I never tried it myself but this SO answer explains how to intercept the console's log calls. Knowing that the console usually have a function named error that is similar to the log function, I'm sure you could apply the same logic to intercept the errors sent to the console.
If you are using chrome, you may refer to the console documentation for more details about the error function. I'm not sure if there's a standard butInternet Explorer and Firefox also has support for console error function.

JS - how to prevent script from stopping after thrown error

How can I prevent the script from stopping after an error has been thrown? Is there something like exception handling in JS?
Console text
Not allowed to load local resource: file:///C:/Users/Temp/image.png
Javascript does have exception handling. There are two possible types of error you can encounter:
1) Places in your application where you proactively guard against errors being thrown, for example, AJAX request. You can handle them like this:
try {
AJAX-code or other code susceptible to errors
} catch(error){
// Log error
}
2) Script errors or compile-time error, for example, undefined variables. In browsers, window.onerror is a global event handler which is called on script or compile errors. However, it's implementation is inconsistent across browsers. You can use it like this:
window.onerror = function(message, url, lineNo) {
// Code to handle the error
}
The main problem with onerror is that no stack trace is passed through which is not very helpful. However, Chromium has added column number and errorObj, so hopefully other browsers will implement the same in near future.
There surely is: try {} catch (exception) {}
Sure, wrap your code inside try/catch:
try
{
//Run some code here
}
catch(err)
{
//Handle errors here
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch
You can use a try/catch/finally block to handle errors:
try {
// Whatever you need
} catch(error) {
// Handle error if one occurs
} finally {
// Last resort
}
Note that you can have multiple catch blocks in-between your try and finally as needed.
Here's some more information.

silent javascript errors

This may be a bad question, but I've noticed that as I'm writing coding along using mootools When I've got some code that goes through callbacks, bindings and generally isn't just a straight forward function call, if there's an error it doesn't get picked up by either Firebug or Chrome's console it just silently fails, and I'm forced to track down the error using trys and such that don't give you handy information like the line of code that's failing. It's like writing code for IE6 all you have to go on is some opaque message like 'can not read 'x' of undefined.'
I realize that the question isn't specific enough to ask 'how do I avoid this' but does anyone else run into this problem and if so how do you work around it? I'm also a little confused how an error could be picked up by a try/catch block, but not the javascript console.
EDIT:
OK, I've come up with something that reproduces the error
say you've got a function
function foo(){
var x = value.blah;
}
if I call that function like foo() I rightly get an reference error in my console. If, however, I call it like
(function(){
foo.attempt();
})()
I get no error in the console, but if I change foo to be
function foo(){
try{
var x = value.blah;
} catch(e){console.log(e)}
}
the console will log e but of course without the handle 'line: whatever' information.
I have considerable experience fiddling with errors in JavaScript. I've mostly used Chrome for building my understanding but most of it applies to Firefox and Internet Explorer as well.
I can immediately debunk your assumption about silent JavaScript errors. They don't exist, Errors always show. There might be a bug in Firefox or the Chrome's webdev, but the errors are there.
The most common way for errors not to show up is because you're catching them yourself. Perhaps prematurely.
I've figured out what I think is the best strategy for catching errors:
1. Always throw things that are Errors or inherited from Errors.
Ex: not: throw "Precondition failed" but throw new Error("Precondition failed").
This is because Errors are weird in JavaScript (I have no other word for it). If you want a stacktrace (and heaven's yes you want a stacktrace) you'll need to throw an Error (and not a string).
2. Don't use window.onerror Not much to say here. It's useless. You have no control over what get's flung to this function. It might be your code, it might be a broken plugin that a visitor uses. Also, no stacktrace.
3. Have one (global) error handler / when to catch errors
JavaScript is event driven. This has some unexpected consequences. Observe the following code:
try {
setTimeout(function () {
throw new Error("nope! :D");
}, 1);
} catch (e) {
console.log(e);
}
You will not see this error. (Firebug / console will catch it though)
This is because the inner function runs in it's own event and the try-catch statement no longer applies to it. The correct way is:
try {
setTimeout(function () {
try {
throw new Error("nope! :D");
} catch (e) {
console.log("Hell yea!", e);
}
}, 1);
} catch (e) {
console.log(e);
}
Or just make a function that wraps a function in a try-catch:
function wrap(wrap_dat_func) {
return function () {
try {
wrap_dat_func.apply(wrap_dat_func, arguments);
} catch (e) {
// send to error handler
}
}
}
Use like:
setTimeout(wrap(function () {
// etc
}), 1);
So basically whenever you generate a new event, wrap the callback in your global try catch function. So wrap call to setTimeout, setInterval all DOM related events like onclick onload ondocumentready, also AJAX calls onreadystatechanged.
How to get proper stacktraces (over events!) is another long winded explanation.

Categories

Resources