Is it possible to stop JavaScript execution? [duplicate] - javascript

This question already has answers here:
How to terminate the script in JavaScript?
(25 answers)
Closed 7 years ago.
Is it possible in some way to stop or terminate JavaScript in a way that it prevents any further JavaScript-based execution from occuring, without reloading the browser?
I am thinking of a JavaScript equivalent of exit() in PHP.

Short answer:
throw new Error("Something went badly wrong!");
If you want to know more, keep reading.
Do you want to stop JavaScript's execution for developing/debugging?
The expression debugger; in your code, will halt the page execution, and then your browser's developer tools will allow you to review the state of your page at the moment it was frozen.
Do you want to stop your application arbitrarily and by design?
On error?
Instead of trying to stop everything, let your code handle the error. Read about Exceptions by googling. They are a smart way to let your code "jump" to error handling procedures without using tedious if/else blocks.
After reading about them, if you believe that interrupting the whole code is absolutely the only option, throwing an exception that is not going to be "caught" anywhere except in your application's "root" scope is the solution:
// creates a new exception type:
function FatalError(){ Error.apply(this, arguments); this.name = "FatalError"; }
FatalError.prototype = Object.create(Error.prototype);
// and then, use this to trigger the error:
throw new FatalError("Something went badly wrong!");
be sure you don't have catch() blocks that catch any exception; in this case modify them to rethrow your "FatalError" exception:
catch(exc){ if(exc instanceof FatalError) throw exc; else /* current code here */ }
When a task completes or an arbitrary event happens?
return; will terminate the current function's execution flow.
if(someEventHappened) return; // Will prevent subsequent code from being executed
alert("This alert will never be shown.");
Note: return; works only within a function.
In both cases...
...you may want to know how to stop asynchronous code as well. It's done with clearTimeout and clearInterval. Finally, to stop XHR (Ajax) requests, you can use the xhrObj.abort() method (which is available in jQuery as well).

You can make a JavaScript typo :D (thinking outside the box here)
thisFunctionDoesNotExistAndWasCreatedWithTheOnlyPurposeOfStopJavascriptExecutionOfAllTypesIncludingCatchAndAnyArbitraryWeirdScenario();
Or something like:
new new

Something like this might work:
function javascript_abort()
{
throw new Error('This is not an error. This is just to abort javascript');
}
Taken from here:
http://vikku.info/codesnippets/javascript/forcing-javascript-to-abort-stop-javascript-execution-at-any-time/

I do:
setTimeout(function() { debugger; }, 5000)
this way I have 5 seconds to interact with UI and then in stops. Las time I used was when I needed to leave custom tooltip visible, to do some styling changes.

No.
Even if you throw an exception, it will only kill the current event loop. Callbacks passed to setTimeout or DOM/XMLHttpRequest event handlers will still run when their time comes.

I am using
return false;
if I want to abort from JavaScript from running further downwards.

If you're in a function you can exit it using return; but that doesn't stop execution of the parent function that called that function.

You can call return early in a function, and at least that function will stop running. You can also just use throw '' to cause an error and stop the current process. But these won't stop everything. setTimeout and setInterval can make delayed functions and functions that run on a time interval, respectively. Those will continue to run. Javascript events will also continue to work as usual.

I know this is old, but I wanted to do this and I have found, in my opinion, a slightly improved solution of the throw answers. Just temporary supress the error messages and reactivate them later using setTimeout :
setTimeout(function() {
window.onerror = function(message, url, lineNumber) {
return false;
};
}, 50); // sets a slight delay and then restores normal error reporting
window.onerror = function(message, url, lineNumber) {
return true;
};
throw new Error('controlledError');

Define a variable inside the JavaScript function, set this variable to 1 if you want ot execute the function and set it to 0 if you want to stop it
var execute;
function do_something()
{
if (execute == 1)
{
// execute your function
}
else
{
// do nothing
}
}

The process is tedious, but in Firefox:
Open a blank tab/window to create a new environment for the script
from the current page
Populate that new environment with the script to execute
Activate the script in the new environment
Close (that is, kill) that new environment to ...
stop or terminate JavaScript this [in a] way to [that it] prevent[s] any further
JavaScript-based execution from occuring, without reloading the browser
Notes:
Step 4 only stops execution of JavaScript in that environment and not the scripts of any other windows
The original page is not reloaded but a new tab/window is loaded with the script
When a tab/window is closed, everything in that environment is gone: all remnants, partial results, code, etc.
Results must migrate back to the parent or another window for preservation
To rerun the code, the above steps must be repeated
Other browsers have and use different conventions.

Related

window.onbeforeunload: not assigned unless I set a breakpoint

I am attempting to set a fairly generic OnBeforeUnload handler:
console.log("WCW - Setting browser warning message");
window.onbeforeunload = function(e) {
e.returnValue = "confirmationMessage";
return e.returnValue;
};
console.log("WCW - onbeforeunload is " +
((window.onbeforeunload ? "set":"still null")));
I understand all I can do is signal the browser to issue a fairly generic warning. In a future iteration I may attempt some self-cleanup before issuing the return.
My problem is that window.onbeforeunload always returns null in the console log after this code runs UNLESS I set a breakpoint on any line (e.g., the first log message) and then just 'continue' when it stops. THEN, it works.
I'm quite sure a "what is wrong" question is pointless, so I'm asking, "do you have any advice on how I can look for what might be the problem?".
I wonder if it's a scope issue? The 2nd log message always says onbeforeunload is non-null... But window is a global, isn't it, and how would a debugger pause fix that?
NOTES:
jQuery is available but using $(window).on('beforeunload' is subject to the same issues as this code
adding a delay (setTimeout) to set the handler does not help; tried 2, 4 & 9 seconds
adding a recursive call to add the handler every 4 seconds while the page is open does not result in the handler being set: window.onbeforeunload returns NULL in the console all the time
periodically, I've seen a jQuery core method attached to the event, but it's rare

Javascript try catch statement

I'm analyzing some code on a website and I came across the following anonymous function followed by a try catch statement. I'm just wondering what the try catch statement is doing at the end there. Is it pre-loading the url so thats it loads more quickly then the anonymous function goes? Also, whats the point is it's not catching any errors.
(function() {
var fired = false;
bsnPop.add("http://www.someurl.com", {
under: !noPopunder,
newTab: false,
forceUnder: true,
shouldFire: function() {
return !fired;
},
cookieExpires: -1,
afterOpen: function(url) {
createCookie();
fired = true;
doSecondPop();
}
});
})();
try {
var hint = document.createElement("link");
hint.rel = "dns-prefetch";
hint.href = "http://www.someurl.com";
document.head.appendChild(hint);
var hint = document.createElement("link");
hint.rel = "preconnect";
hint.href = "http://www.someurl.com";
document.head.appendChild(hint);
} catch (e) {}
With reference to the link types list on MDN, "dns-prefetch" and "preconnect" are listed as experimental. They do not appear in the list of "rel" values for link types of link elements in HTML5
So the code is using experimental technology on the web which might throw an error in some browsers. To prevent stopping the application and logging an exception on the console, the code is placed in a try block with a catch block that ignores the error.
In answer to question details, the anonymous function in the IIFE is invoked and passes an object containing parameters and callbacks in a call to bsnPop.add. It does not appear to create a popup window at this stage.
Next code within the try block attempts to speed up access to the web site by requesting DNS lookup of the website's name in advance, and to open a connection to the site before attempting to retrieve content.
The code is placed in the try block to accommodate the possibility of a browser throwing an exception if the requested operations are not supported. The application does not consider lack of support an error and wants to continue anyway.
The end result is that if dns-prefetch or preconnect are supported the browser can take the hint and perform the operations. If they are not supported any error generated is ignored and code continues at the next statement - connecting to the website later will have to proceed at normal speed.

Continue test if a click error occurs

I'm running CasperJS with PhantomJS. I have it going to a url and clicking on an element based on XPath. This could happen several times without a problem, until, I suspect there is a delay in the page loading, it can't find the XPath, it throws an error and stops the test. I would like it to continue through the error. I don't want to wait+click any longer than I already am, as there are many clicks going on, and an error can be at a random click, waiting on every click is counter productive.
I have tried putting the whole test into a try catch, it wouldn't catch.
The only handling I could find just gave out more information on the error, still stopped the test.
I would wait for the selector you want to run, with a short timeout. In the success function do your click, in the timeout function report the problem (or do nothing at all).
For instance:
casper.waitForSelector('a.some-class', function() {
this.click('a.some-class');
}, function onTimeout(){
this.echo("No a.some-class found, skipping it.");
},
100); //Only wait 0.1s, as we expect it to already be there
});
(If you were already doing a casper.wait() just before this, then replace that with the above code, and increase the timeout accordingly.)
You cannot catch an error in something that is executed asynchronously. All then* and wait* functions are step functions which are asynchronous.
Darren Cook provides a good reliable solution. Here are two more which may work for you.
casper.options.exitOnError
CasperJS provides an option to disable exiting on error. It work reliably. The complete error with stacktrace is printed in the console, but the script execution continues. Although, this might have adverse effects when you also have other errors on which you may want to stop execution.
try-catch
Using a try-catch block works in CasperJS, but only on synchronous code. The following code shows an example where only the error message is printed without stacktrace:
casper.then(function() {
try {
this.click(selector);
} catch(e){
console.log("Caught", e);
}
});
or more integrated:
// at the beginning of the script
casper.errorClick = function(selector) {
try {
this.click(selector);
} catch(e){
console.log("Caught", e);
return false;
}
return true;
};
// in the test
casper.then(function() {
this.errorClick("someSelector");
});

How to break while loop outside it

this is not a common condition, but what's the misuse of it?
var t = true;
setTimeout(function(){
t=false;
},1000);
while(t){
//loop...
//if t==false, break loop.
}
another condition, it causes endless loop too:
button.onlcick = function(){
t = false;
}
JavaScript is single-threaded; setTimeout callback won't be called when you're blocking the main event loop with that while (while (t) { ... }).
If you're running your code in browser, you can't really do anything about it but writing your code in other way;
Instead of blocking the main event loop, you can use Promises Pattern.
If you're running your code in something like node you can use native modules, making you able to create threads (like threads_a_gogo.)
Because the while loop never exits, your other code is never run when something is done synchronously. My best offer for you would be not to use a while loop and instead have a recurring event such as setTimeout and make the timeout run itself when complete.
This way you're not creating a closed environment.
It won't work because javascript is not multithreaded - until your current thread of execution ends (and it won't as long as you're running your while loop), no other code is executed (no timeout call) and the UI is frozen (button clicks will not respond).
There might be a way to do something like that with the new Web Workers feature in html5, but as of now i'm not able to tell with certainty.
you can use labels with break condition like
outer:while()
{
//code
if()
break outer;
}

How to terminate the script in JavaScript?

How can I exit the JavaScript script much like PHP's exit or die? I know it's not the best programming practice but I need to.
"exit" functions usually quit the program or script along with an error message as paramete. For example die(...) in php
die("sorry my fault, didn't mean to but now I am in byte nirvana")
The equivalent in JS is to signal an error with the throw keyword like this:
throw new Error();
You can easily test this:
var m = 100;
throw '';
var x = 100;
x
>>>undefined
m
>>>100
JavaScript equivalent for PHP's die. BTW it just calls exit() (thanks splattne):
function exit( status ) {
// http://kevin.vanzonneveld.net
// + original by: Brett Zamir (http://brettz9.blogspot.com)
// + input by: Paul
// + bugfixed by: Hyam Singer (http://www.impact-computing.com/)
// + improved by: Philip Peterson
// + bugfixed by: Brett Zamir (http://brettz9.blogspot.com)
// % note 1: Should be considered expirimental. Please comment on this function.
// * example 1: exit();
// * returns 1: null
var i;
if (typeof status === 'string') {
alert(status);
}
window.addEventListener('error', function (e) {e.preventDefault();e.stopPropagation();}, false);
var handlers = [
'copy', 'cut', 'paste',
'beforeunload', 'blur', 'change', 'click', 'contextmenu', 'dblclick', 'focus', 'keydown', 'keypress', 'keyup', 'mousedown', 'mousemove', 'mouseout', 'mouseover', 'mouseup', 'resize', 'scroll',
'DOMNodeInserted', 'DOMNodeRemoved', 'DOMNodeRemovedFromDocument', 'DOMNodeInsertedIntoDocument', 'DOMAttrModified', 'DOMCharacterDataModified', 'DOMElementNameChanged', 'DOMAttributeNameChanged', 'DOMActivate', 'DOMFocusIn', 'DOMFocusOut', 'online', 'offline', 'textInput',
'abort', 'close', 'dragdrop', 'load', 'paint', 'reset', 'select', 'submit', 'unload'
];
function stopPropagation (e) {
e.stopPropagation();
// e.preventDefault(); // Stop for the form controls, etc., too?
}
for (i=0; i < handlers.length; i++) {
window.addEventListener(handlers[i], function (e) {stopPropagation(e);}, true);
}
if (window.stop) {
window.stop();
}
throw '';
}
Even in simple programs without handles, events and such, it is best to put code in a main function, even when it is the only procedure :
<script>
function main()
{
//code
}
main();
</script>
This way, when you want to stop the program you can use return.
There are many ways to exit a JS or Node script. Here are the most relevant:
// This will never exit!
setInterval((function() {
return;
}), 5000);
// This will exit after 5 seconds, with signal 1
setTimeout((function() {
return process.exit(1);
}), 5000);
// This will also exit after 5 seconds, and print its (killed) PID
setTimeout((function() {
return process.kill(process.pid);
}), 5000);
// This will also exit after 5 seconds and create a core dump.
setTimeout((function() {
return process.abort();
}), 5000);
If you're in the REPL (i.e. after running node on the command line), you can type .exit to exit.
If you don't care that it's an error just write:
fail;
That will stop your main (global) code from proceeding.
Useful for some aspects of debugging/testing.
Place the debugger; keyword in your JavaScript code where you want to stop the execution. Then open your favorite browser's developer tools and reload the page. Now it should pause automatically. Open the Sources section of your tools: the debugger; keyword is highlighted and you have the option to resume script execution.
I hope it helps.
More information at:
https://developer.mozilla.org/de/docs/Tools/Debugger
http://www.w3schools.com/js/js_debugging.asp
Javascript can be disabled in devtools: ctrl+shift+j followed cltf+shift+p then type disable javascript
Possible options that mentioned above:
window.stop(); // equivalent to the 'stop' button in the browser
debugger; // debugs
for(;;); // crashes your browser
window.location.reload(); // reloads current page
If page is loaded and you don't want to debug crash or reload:
throw new Error();
Additionally clear all timeouts
var id = window.setTimeout(function() {}, 0);
while (id--) {
window.clearTimeout(id);
}
abort DOM/XMLHttpRequest
$.xhrPool = [];
$.xhrPool.abortAll = function() {
$(this).each(function(i, jqXHR) {
jqXHR.abort();
$.xhrPool.splice(i, 1);
});
}
$.ajaxSetup({
beforeSend: function(jqXHR) { $.xhrPool.push(jqXHR); },
complete: function(jqXHR) {
var i = $.xhrPool.indexOf(jqXHR);
if (i > -1) $.xhrPool.splice(i, 1);
}
});
remove all event listeners including inline
$("*").prop("onclick", null).off();
this removes scripts and recreates elements without events
$('script').remove();
$('*').each(function(){
$(this).replaceWith($(this).clone());
});
If jQuery is not available on the webpage copy-paste source code into a console.
There're might be other stuff. Let me know in a comment.
In my case I used window.stop.
The window.stop() stops further resource loading in the current browsing context, equivalent to the 'stop' button in the browser.
Because of how scripts are executed, this method cannot interrupt its parent document's loading, but it will stop its images, new windows, and other still-loading objects.
Usage: window.stop();
(source)
In JavaScript multiple ways are there, below are some of them
Method 1:
throw new Error("Something went badly wrong!");
Method 2:
return;
Method 3:
return false;
Method 4:
new new
Method 5:
write your custom function use above method and call where you needed
Note:
If you want to just pause the code execution you can use
debugger;
I think this question has been answered, click here for more information. Below is the short answer it is posted.
throw new Error("Stop script");
You can also used your browser to add break points, every browser is similar, check info below for your browser.
For Chrome break points info click here
For Firefox break points info click here
For Explorer break points info click
For Safari break points info click here
If you're looking for a way to forcibly terminate execution of all Javascript on a page, I'm not sure there is an officially sanctioned way to do that - it seems like the kind of thing that might be a security risk (although to be honest, I can't think of how it would be off the top of my head). Normally in Javascript when you want your code to stop running, you just return from whatever function is executing. (The return statement is optional if it's the last thing in the function and the function shouldn't return a value) If there's some reason returning isn't good enough for you, you should probably edit more detail into the question as to why you think you need it and perhaps someone can offer an alternate solution.
Note that in practice, most browsers' Javascript interpreters will simply stop running the current script if they encounter an error. So you can do something like accessing an attribute of an unset variable:
function exit() {
p.blah();
}
and it will probably abort the script. But you shouldn't count on that because it's not at all standard, and it really seems like a terrible practice.
EDIT: OK, maybe this wasn't such a good answer in light of Ólafur's. Although the die() function he linked to basically implements my second paragraph, i.e. it just throws an error.
throw "";
Is a misuse of the concept but probably the only option. And, yes, you will have to reset all event listeners, just like the accepted answer mentions. You would also need a single point of entry if I am right.
On the top of it: You want a page which reports to you by email as soon as it throws - you can use for example Raven/Sentry for this. But that means, you produce yourself false positives. In such case, you also need to update the default handler to filter such events out or set such events on ignore on Sentry's dashboard.
window.stop();
This does not work during the loading of the page. It stops decoding of the page as well. So you cannot really use it to offer user a javascript-free variant of your page.
debugger;
Stops execution only with debugger opened. Works great, but not a deliverable.
If you just want to stop further code from executing without "throwing" any error, you can temporarily override window.onerror as shown in cross-exit:
function exit(code) {
const prevOnError = window.onerror
window.onerror = () => {
window.onerror = prevOnError
return true
}
throw new Error(`Script termination with code ${code || 0}.`)
}
console.log("This message is logged.");
exit();
console.log("This message isn't logged.");
This little function comes pretty close to mimicking PHP's exit(). As with the other solutions, don't add anything else.
function exit(Msg)
{
Msg=Msg?'*** '+Msg:'';
if (Msg) alert(Msg);
throw new Error();
} // exit
If you use any undefined function in the script then script will stop due to "Uncaught ReferenceError". I have tried by following code and first two lines executed.
I think, this is the best way to stop the script. If there's any other way then please comment me. I also want to know another best and simple way. BTW, I didn't get exit or die inbuilt function in Javascript like PHP for terminate the script. If anyone know then please let me know.
alert('Hello');
document.write('Hello User!!!');
die(); //Uncaught ReferenceError: die is not defined
alert('bye');
document.write('Bye User!!!');
I am using iobroker and easily managed to stop the script with
stopScript();
I know this is old, but if you want a similar PHP die() function, you could do:
function die(reason) {
throw new Error(reason);
}
Usage:
console.log("Hello");
die("Exiting script..."); // Kills script right here
console.log("World!");
The example above will only print "Hello".
Wrapp with a function
(function(){
alert('start')
return;
alert('no exec')
})
i use this piece of code to stop execution:
throw new FatalError("!! Stop JS !!");
you will get a console error though but it works good for me.
To stop script execution without any error, you can include all your script into a function and execute it.
Here is an example:
(function () {
console.log('one');
return;
console.log('two');
})();
The script above will only log one.
Before use
If you need to read a function of your script outside of the script itself, remember that (normally) it doesn't work: to do it, you need to use a pre-existing variable or object (you can put your function in the window object).
The above code could be what you don't want: put an entire script in a function can have other consequences (ex. doing this, the script will run immediately and there isn't a way to modify its parts from the browser in developing, as I know, in Chrome)
This is an example, that,
if a condition exist, then terminate the script.
I use this in my SSE client side javascript, if the
<script src="sse-clint.js" host="https://sse.host" query='["q1,"q2"]' ></script>
canot be parsed right from JSON parse ...
if( ! SSE_HOST ) throw new Error(['[!] SSE.js: ERR_NOHOST - finished !']);
... anyway the general idea is:
if( error==true) throw new Error([ 'You have This error' , 'At this file', 'At this line' ]);
this will terminate/die your javasript script
Simply create a BOOL condition ,
no need for complicated code here..
If even once you turn it to true/ or multiple times,
it will both give you one line of solution/not multiple -
basically simple as that.
Not applicable in most circumstances, but I had lots of async scripts running in the browser and as a hack I do
window.reload();
to stop everything.
This code will stop execution of all JavaScripts in current window:
for(;;);
Example
console.log('READY!');
setTimeout(()=>{
/* animation call */
div.className = "anim";
console.log('SET!');
setTimeout(()=>{
setTimeout(()=>{
console.log('this code will never be executed');
},1000);
console.log('GO!');
/* BOMB */
for(;;);
console.log('this code will never be executed');
},1000);
},1000);
#div {
position: fixed;
height: 1rem; width: 1rem;
left: 0rem; top: 0rem;
transition: all 5s;
background: red;
}
/* this <div> will never reached the right bottom corner */
#div.anim {
left: calc(100vw - 1rem);
top: calc(100vh - 1rem);
}
<div id="div"></div>
i use return statement instead of throw as throw gives error in console. the best way to do it is to check the condition
if(condition){
return //whatever you want to return
}
this simply stops the execution of the program from that line, instead of giving any errors in the console.

Categories