I have some code in my application that wraps function.apply and function.call in try/catch blocks. It's handy for catching errors and building up a pseudo-stack using arguments.caller but it plays havoc with IE's debugger.
I can turn off the wrapping with a url parameter but I'd like to turn it off automatically if the debugger is attached. I can't find a way to detect the debugger. Any ideas?
Not sure for IE8, but you can detect if the debugger is running in IE9/IE10/IE11 by checking:
var isIeDebugging = !!window.__IE_DEVTOOLBAR_CONSOLE_COMMAND_LINE || ('__BROWSERTOOLS_DOMEXPLORER_ADDED' in window);
e.g. see http://jsbin.com/IJOwuje/5
However, in IE9/IE10 this is set to true for a window that has run the debugger just once, even if the debugger now closed.
Also in IE11 the various window.__BROWSERTOOLS* keys seem to only appear depending upon which debugger tab is open or used, so not 100% reliable for checking if the debugging frame is open...
This isn't the answer you wanted, but I've handled this in the past by having a small bit of loader JS that begins by checking the hash, if any, in the URL, for a secret code, like:
mysite.com/#mXVa
So the loader checks and if location.hash == 'mXVa', my loader loads the debug versions of all the scripts on the page (no try/catch, etc) rather than the minified, error-eating variety.
Related
I am working with SystemJS and I have a pseudo-bootstrapper file that I use to check to make sure certain conditions are met before the loading of the main scripts to execute the page load. Here is a snippet of that code.
var obj = document.createElement('script');
obj.src = 'jspm_packages/system.js';
document.body.appendChild(obj);
This code does NOT execute the script, yet it does load it with a 200 code as evidenced by the network tab within the IE dev tools. There should be a global object "System" created, but it does not exist. Looking through the DOM, the object is properly created and appended to the body.
Does anyone know if this is strictly an issue with IE and SystemJS? I have no idea what's going on. I'm pulling my hair out, as per usual with the demon that is IE. I should note that every other browser works as expected, providing the "System" global variable.
EDIT Further testing has assured that this is not an issue with appendChild, as other scripts using the same method, execute on load just fine.
Reading this article tells us that your script may not run in IE11. The line in particular which is of interest is:
"Script elements with external resources should no longer execute during appendChild."
This appears to be what's happening.
EDIT: An alternate approach could be taken.
It would be a good idea to do condition checks on the server side before sending the response if you want to change page loading at the system.js level. If that is not possible then I'd suggest doing a redirect after the condition checks instead of appendChild.
The answer is that IE versions < Edge do not support promises. I needed a polyfill for IE 11.
Similar to other questions here, like this one.
Is there a way to break on the change of a variable value in any JavaScript debugger? (like IE Developer tools, Visual Studio, or Firebug)?
I guess it's something like a "watch variable", but I want to be able to see the callstack and pause it when the change to the variable actually occurs.
An alternative approach might be to override the value setting with a custom setter, and put a breakpoint in that, but unfortunately that won't work for IE AFAIK.
UPDATE
It appears that this type of behavior is available at least for unmanaged code written in C++ So I thought maybe a javascript engine written in C++ (Google's V8) might have something similar, but that doesn't appear to have what I want either.
You don't even need an IDE - you can use "Object.watch()":
Object.Watch Tutorial
If you use any one debugger, I'd strongly recommend Firebug. For all your Javascript, HTML and CSS needs :-):
http://getfirebug.com/javascript
===========================================================
Update for 2019:
Object.Watch is Ancient History. Uncoincidentally, it's unavailable in most contemporary browsers.
My personal favorite JS debugging tool these days is Chrome Developer Tools.
My personal favorite JS IDE (for Angular, .Net Core, etc) is Microsoft Visual Studio Code (MSVC).
You can do just about any "expected" debugging operation - including set watches - with the Chrome debugger (just as you could with FF Firebug).
Chrome debugger is well integrated with the MSVC IDE.
Both are "free" (at least "free as in beer"); both run well on Windows, Mac and Linux.
I'm having success with this library in Chrome and it looks to support all major browsers.
https://gist.github.com/eligrey/384583
Just include the .js file, then call:
yourObject.watch('someProperty', function() {
doWhatYouWant();
debugger;
console.write('this too');
alert('Object Changed'); //etc
});
I don't know if I misunderstood your question. If you want to watch an expression and stop when it reaches a certain value while in a js debugging session in Chrome Developer Tools, it's rather trivial.
You can simply put a breakpoint on the line where the value you want to check is, then click with right mouse button on it and select "Edit breakpoint...". A dialog will pop up prompting for an expression, where execution will stop when its value its true.
For instance, let's say you have a loop and you are adding one unit to a variable inside it and want to stop execution when the variable equals to 3. The expression in loop would look like this:
n = i++;
You must set your breakpoint on that line and the expression to watch (after prompted by "Edit breakpoint...") would be n == 3. When running your code it will stop there when your variable reaches that value.
You'll notice your condition is set because your breakpoint turns orange instead of blue.
Chrome on iOS appears to create an XMLHttpRequest object when you include an external JavaScript file. It seems to assign this object to a global variable with the identifier a, overwriting anything you may have already had in there.
Test case:
HTML file (test.html):
<!-- ... -->
<script>
var a = 1; // Value is not important for this demonstration
</script>
<script src="test.js"></script>
<!-- ... -->
External JavaScript file (test.js):
setTimeout(function () {
document.write(a); // [object XMLHttpRequest]
a.onreadystatechange = function () {
document.write(a.readyState); // Alternates between "1" and "4"
};
}, 100);
The XMLHttpRequest appears to repeatedly make a request (to somewhere... routing the device connection through a proxy and monitoring requests doesn't show up anything) and the onreadystatechange event handler is repeatedly executed.
Some more observations:
This only seems to happen some time after page load (hence the setTimeout)
When it does happen, there is also a window.__gchrome_CachedRequest property
__gchrome_CachedRequest === a
It doesn't seem to happen in older versions of iOS Chrome (not sure which version it first occurs in though)
Has anyone come across this before? Is there a way I can stop it from happening (Note... I cannot rename a)? If anyone knows why it does this I would love to find out.
Update
I've just noticed that this actually happens with inline scripts too, not just when you include an external script. I didn't notice this initially because I didn't have the setTimeout call in there. So it looks like it actually just always happens some time after page load.
From the discussion we had in comments, it looks like Chrome is using a with statement to layer some of its own stuff over the top of window properties. It probably does this because those properties would not normally be overwritable. The delay is most likely down to how soon Chrome can inject its own script into the UIWebView (browsers on iOS are forced to use the underlying UIWebView object rather than their own engines) after a page starts loading.
If all this speculation is actually true, then there's simple solution, other than to access window.a instead of a or take the power back and use your own with statement:
with (window)
eval(myScript);
Hardly a solution anyone would relish implementing, but might be your only option.
Similar to other questions here, like this one.
Is there a way to break on the change of a variable value in any JavaScript debugger? (like IE Developer tools, Visual Studio, or Firebug)?
I guess it's something like a "watch variable", but I want to be able to see the callstack and pause it when the change to the variable actually occurs.
An alternative approach might be to override the value setting with a custom setter, and put a breakpoint in that, but unfortunately that won't work for IE AFAIK.
UPDATE
It appears that this type of behavior is available at least for unmanaged code written in C++ So I thought maybe a javascript engine written in C++ (Google's V8) might have something similar, but that doesn't appear to have what I want either.
You don't even need an IDE - you can use "Object.watch()":
Object.Watch Tutorial
If you use any one debugger, I'd strongly recommend Firebug. For all your Javascript, HTML and CSS needs :-):
http://getfirebug.com/javascript
===========================================================
Update for 2019:
Object.Watch is Ancient History. Uncoincidentally, it's unavailable in most contemporary browsers.
My personal favorite JS debugging tool these days is Chrome Developer Tools.
My personal favorite JS IDE (for Angular, .Net Core, etc) is Microsoft Visual Studio Code (MSVC).
You can do just about any "expected" debugging operation - including set watches - with the Chrome debugger (just as you could with FF Firebug).
Chrome debugger is well integrated with the MSVC IDE.
Both are "free" (at least "free as in beer"); both run well on Windows, Mac and Linux.
I'm having success with this library in Chrome and it looks to support all major browsers.
https://gist.github.com/eligrey/384583
Just include the .js file, then call:
yourObject.watch('someProperty', function() {
doWhatYouWant();
debugger;
console.write('this too');
alert('Object Changed'); //etc
});
I don't know if I misunderstood your question. If you want to watch an expression and stop when it reaches a certain value while in a js debugging session in Chrome Developer Tools, it's rather trivial.
You can simply put a breakpoint on the line where the value you want to check is, then click with right mouse button on it and select "Edit breakpoint...". A dialog will pop up prompting for an expression, where execution will stop when its value its true.
For instance, let's say you have a loop and you are adding one unit to a variable inside it and want to stop execution when the variable equals to 3. The expression in loop would look like this:
n = i++;
You must set your breakpoint on that line and the expression to watch (after prompted by "Edit breakpoint...") would be n == 3. When running your code it will stop there when your variable reaches that value.
You'll notice your condition is set because your breakpoint turns orange instead of blue.
I'd like to set a breakpoint in a "Cart.add" function in the Chrome or Safari JavaScript debuggers. Problem is, this function is defined in a large minified JS file, and doesn't exist on a line by itself.
Some documentation says that the WebKit-based debuggers support "break" or "debug" commands in the debug console, but those don't seem to work in newer versions of the debugger.
Setting a breakpoint on that line of the JS file doesn't work either, since there are lots of functions on that line.
Any suggestions?
In Chrome when you open Scripts tab you can prettify selected file by clicking on { } button ("Pretty print") at the bottom. After that you can find your line and set a breakpoint. The code will remain prettified with breakpoints in place after a page refresh.
The debugger statement is probably what you're looking for.
Evaluating the DebuggerStatement production may allow an implementation to cause a breakpoint when run under a debugger. If a debugger is not present or active this statement has no observable effect.
The production DebuggerStatement : debugger ; is evaluated as follows:
If an implementation defined debugging facility is available and enabled, then
a. Perform an implementation defined debugging action.
b. Let result be an implementation defined Completion value.
Else
a. Let result be (normal, empty, empty).
Return result.
The break statement is for exiting loops and switch statements and has nothing to do with debugging.
The real solution though is to not bugger your code in the first place :)
1) The error message should give you a link to the source code in the
Sources tab. Click on that link to get taken to the transpiled code.
2) Click the "{ }" icon at the bottom of the source code in the
Sources tab to format the transpiled code for easier debugging.
3)Stick a breakpoint at the line that is failing.
4) Reproduce the
problem again. This time, it should break at the breakpoint before
the error occurs.
5) Examine the local variables and call stack to
determine what exactly is going wrong.
For chrome users, you'll want to enable automatic pretty print in the experimental features.
setting your breakpoint should work now.
If you have saved the webpage then beautify your js file using jsbeautifier.org which formats your entire script. Then replace your js content with the beautified version. From here you can debug your JS easily