Is there a way to set breakpoints when specific functions are about to execute?
It needn't be an explicit breakpoint - I just want execution to pause when a console.log() is about to be called.
Or should I resort to this method.
I prefer to accomplish this without modifying my code, or manually setting breakpoints at every console.log.
Yes that's the trick. Create a custom logging function, put debugger in it and call console.log and you have what you wanted:
function log(message) {
debugger;
console.log(message) ;
}
Edit:
You can also replace console.log by a similar fonction that calls the original:
var clog = console.log;
console.log = function(message) {
if(message == '...') {
debugger;
}
clog.apply(console, arguments);
}
This code will affect all log calls within your page. The check is to catch a certain message. Remove it to stop always.
How about call this at the very start that add a pause break for your every console.log?
This replace the original console.log, pause break first, then call the orignal console.log for you. And this will be apply on all console.log calls.
(function () {
var oldLog = console.log;
console.log = function() {
debugger;
oldLog.apply(console, arguments);
}
})();
console.log('hello');
Related
The usual suggestion (Capturing javascript console.log?) for a js console.log interceptor falls short on two counts, both serious:
(i) all calls in the actual browser console now appear to come from the same line - where the new function is defined - rather then where the call is done
(ii) the intercepted arguments are not yet formatted the way console.log does (i.e. the % replacement goodies, %o, in particular):
(function() {
function send_stuff(){ /* Deal with console arguments. */ }
var oldLog=console.log;
console.log=function(msg) {
oldLog.apply(this,arguments);
send_stuff(Array.prototype.slice.call(arguments).join());
}
}())
console.log("test");
console.log("Hello %s", "Bob");
console.log("Here is an object %o", { stuff: "thing" });
Maybe something better (e.g. something able to capture the actual buffer content of console.log) has been devised.
Edit:
To clarify the multiple arguments failure: besides expanding the file/line info, console.log also does some clever replacements - a-la-printf - of % sequences. Of particular interest is the %o sequence, where a deep-ish dump of the subsequent object(s) is expanded, and put to good use by the browser's console window. This cannot be replicated, unless one is willing to basically reimplement its logic (unnecessarily and , in all likelyhood, unefficiently)
Cheers,
It looks like the behavior of console.log changed a little bit and now the masks are working but you are still getting the line of oldLog.apply(this,arguments); in the console. One thing you could do is to use console.error instead, this is going to show the call stack that you can use to see what line originally called your modified log method.
Another solution is to throw an error to get the line number from the call stack, like this
(function () {
function origin() {
try {
throw Error('');
} catch (err) {
return err.stack.split('\n').slice(-1)[0];
}
}
function send_stuff() { /* Deal with console arguments. */ }
var oldLog = console.log;
console.log = function (msg) {
oldLog.call(this, ...arguments, origin());
send_stuff(Array.prototype.slice.call(arguments).join());
};
})();
console.log("test");
console.log("Hello %s", "Bob");
console.log("Here is an object %o", {
stuff: "thing"
});
I've been hunting around Google and various JavaScript websites, but I've yet to find an answer for this. Is there any way that I could use JavaScript/JQuery to monitor events such as console.log()?
For example, I'd like to trigger an even when a separate, cumbersome-to-deal with script calls console.log('foo'); When using any web inspector with a JavaScript console, it's easy to see foo pop up when the script logs it, but is there a way I can hook that event with a different script?
Code borrowed from Can I extend the console object (for rerouting the logging) in javascript?:
(function() {
var exLog = console.log;
console.log = function(msg) {
exLog.apply(console, arguments);
alert(msg);
}
})()
This should allow you to do just about anything when console.log() has been executed, as long as this code runs before console.log() is executed.
While you cannot extend console, you can wrap each of it's methods. The code below intercepts every logging method and records each call in a variable called log.
var actualConsole = window.console;
var c = window.console = {};
var log={};
for (var m in actualConsole){
if (typeof console[m] ==='object'){
c[m]=console[m];
}else if (typeof actualConsole[m] ==='function'){
c[m]=function () {
var args = Array.prototype.slice.call(arguments);
log[this]=log[this]||[];
log[this].push(args);
actualConsole[this].apply(actualConsole,args);
}.bind(m);
}// else - nothing else expected
}
console.log('log',1);
console.log('log',2);
console.error('error',1);
console.warn('warn',1);
actualConsole.log('log:',log);
Log looks like:
{"log":[["log",1],["log",2]],"error":[["error",1]],"warn":[["warn",1]]}
If I receive an error from a framework or an error from the browser. Basically a runtime error of any kind. Without modifying the framework, is it possible for me to override the console logs that these frameworks make and the browser's errors. I want to use my own framework with own error handling system when informing the user of errors of practically anything runtime (not syntax errors). I don't know if you would class it all as runtime errors because of the way javascript is executed in the browser but hopefully you will get me?
Is this possible if all the frameworks are written in Javascript?
How is this achieved?
What considerations do I have to make between different browsers?
Thanks
You are probably looking for a try-catch block:
try {
alert(foo);
} catch(e) {
alert('The code got the following error: '+e.message);
}
Whenever the code between the try {} receives an error, the catch(e) {} block will execute, with the argument e being the error object for the error that occurred. In this case, the variable foo is not defined, so executing this code will result in an alert message saying "The code got the following error: foo is not defined"
While not over-riding console.log, you may be achieve the same effect by overriding window.onerror.
From the MDN documentation
window.onerror = function myErrorHandler(errorMsg, url, lineNumber) {
// Log the error here -- perhaps using an AJAX call
}
You could try overriding the console.log() function.
//Save original reference
var originalConsole = console;
//Override
console = {};
console.log = function()
{
//According to MDN the console.log function can receive a variable number of params
for(var i=0; i<arguments.length; i++)
{
//Make your changes here, then call the original console.log function
originalConsole.log("Change something: "+arguments[i]);
}
//Or maybe do something here after parsing all the arguments
//...
}
console.log("one", "two");
JSFiddle here.
You can override the console logs by creating a "console" object and overriding it's .log() function:
var console = {};
console.log = function(){};
Some browsers require this to be added to the window object directly; so, for browser compatibility, also add:
window.console = console;
Additionally, you can override other console functions (e.g. console.info, console.warn and console.error) if you're using those too.
Also, consider reading this blog post from Udi Talias on overriding the console functions. Good and quick read!
You can custom your console.log here
// copy the original
let originalConsole = Object.assign({}, console);
// do something with your log.
console.log = (value) => {
//some cool condition
if (true) {
value = "new_log : " + value
}
originalConsole.log(value);
};
In my jQuery scripts, when the user closes a menu with an animation, I have to call a function after the closing animation is finished. I want to assign this function dynamically by calling a function openStrip() with a parameter. My code looks like:
var FUNCTION_JUST_AFTER_MENU_CLOSE = function(){};
function openStrip(stripId){
FUNCTION_JUST_AFTER_MENU_CLOSE = function(){
createStrip(stripId);
});
}
if I call openStrip("aStripId"), I expect FUNCTION_JUST_AFTER_MENU_CLOSE to be:
// #1
function(){
createStrip("aStripId");
}
whereas my current code gives:
//#2
function(){
createStrip(stripId);
}
i.e, the parameter passed to the function openStrip() is lost while assigning the function() to the variable FUNCTION_JUST_AFTER_MENU_CLOSE.
How can I avoid this.
EDIT: I discovered that my code is actually working. The problem was elsewhere. I got confused because when I looked at Chrome's debugger, it was showing me the function definition as is (#2 in above). But when it actually went down executing that function later in the code, it did evaluate the values of the passed argument, and endedup executing #1.
Thanks for the answer though. I am marking it correct because that is perhaps a better way of assigning the function.
The best way is to return a function, from openStrip like this
function openStrip(stripId) {
return function() {
createStrip(stripId);
};
}
For example,
function openStrip(stripId) {
return function() {
console.log(stripId);
};
}
openStrip("aStripId")();
# aStripId
openStrip("bStripId")();
# bStripId
You can even assign the function objects returned to different variables and use them later on
var aStrip = openStrip("aStripId");
aStrip();
# aStripId
aStrip();
# aStripId
I have code that looks something like this:
function pathfind (start,end,map)
{
this.Init = function ()
{
this.open_node = new Array();
this.open_node.push(start);
console.log(this.open_node);
this.Loop();
}
this.Loop = function ()
{
//Some code here
}
this.Init();
}
For some reason when I push "start" to this.open_node and I log its value, I get "undefined". However, after some bug testing I realized that commenting out this.Loop(); in this.Init causes push to function properly and console.log to return [start] as it should. Can anyone explain why on earth this behavior would occur?
EDIT: I'm calling
pathfind({x:2,y:2},{x:24,y:24},parsemap(25,25));
After further research I found that console.log doesn't execute immediately in Chrome. Hence the outdated reports.
Your code executes pathfind function that returns undefined(and it should be this way) but you wait for result from this.Init function. Should probably execute it instead of pathfind.