I am using console.log(...) for debugging purposes. However the console gets messages from iframes too(I am using iframes in my HTML code). How can I see only the logs that I sent and not the logs that came from iframes?
This is kinda old post, but still, for those who will come here for help:
In Chrome you can check the "Selected context only" (screenshot here) option, and it'll be this.
How about adding a snippet in your JavaScript to catch errors thrown by the iFrames?
You could replace [IFRAME ERROR MESSAGE] with the errors your iFrame is throwing. If the snippet catches an error from an iFrame, it will do nothing, otherwise, it will output the error to the console:
window.onerror = function (msg, url, line) {
if (msg == "[IFRAME ERROR MESSAGE]") {
return true
}
else {
//do nothing
}
}
Make sure to put this code as early as possible in your script.
Reference
Reference 2
Working example (save it as test.html and open in chrome):
<button onclick="myfunction()">x is not defined</button>
<button onclick="myfunction2()">y is not defined</button>
<script>
window.onerror = function (msg, url, line) {
if (msg == "Uncaught ReferenceError: x is not defined") {
return true
}
else {
//do nothing
}
}
function myfunction(){
console.log(x);
}
function myfunction2(){
console.log(y);
}
</script>
In this example, you will see that no errors will be outputted in the console when you click the first button, but you will see errors when you click the second button.
Just filter out (using the Chrome's filter box) the log messages from the iFrame.
In Chrome's Console tab you have a Filter box, type there the name of the file you want to filer out, with a minus sign "-" before the file name.
You can filter multiply files, using space as a delimiter.
For example:
-LogUtil.js -FrameService.js
Or instead of typing, just right click on a log message, and select Hide message from <file_name>.
You can add something like "?nofrm=1" to the src attribute of the page's script tags you want to see logs for. Then in Chrome you can type "nofrm" into the filter to get logs from only them scripts. Add "?nofrm=1" to the url if you want to log inline scripts too.
I wrote a logger service for the client side. I used a pattern by which I can filter out the logs/errors etc which are being produced by my script and not by the iframes.
function logger(){
var pattern="PC:";
var info=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.info.apply(console, arguments);
}
var log=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.log.apply(console, arguments);
}
var warning=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.warn.apply(console, arguments);
}
var debug=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.debug.apply(console, arguments);
}
var error=function(){
Array.prototype.unshift.apply(arguments, [pattern]);
console.error.apply(console, arguments);
}
return {
info:info,
log:log,
warning:warning,
debug:debug,
error:error
}
}
Here "PC:" is the pattern
You can filter the logs by source / hide from other scripts than you own. It will of course only be a solution if you get logs from a smaller number of scripts
Related
I am writing a monitoring addon for the website.
Is it possible to get logs and errors from the chrome console by JavaScript?
I tried to override the console log and other functions but it only recorded logs generated by my own code.
I would like to catch logs and errors output by 3rd party lib as well. for example, if I am writing a website using jQuery I would like to collect all logs and errors output by jquery as well.
thanks
How about trying this?
You can modify the global console.log
const overridedConsole = (function(originConsole){
return {
log: function(text){
originConsole.log(text);
// maybe save?
},
info: function (text) {
originConsole.info(text);
// maybe save?
},
warn: function (text) {
originConsole.warn(text);
// maybe save?
},
error: function (text) {
originConsole.error(text);
// maybe save?
}
};
}(window.console));
//Then redefine the old console
window.console = overridedConsole;
I have the code below. Which injects the script in head of the page correctly. But why is the "createReview called" message never printed to the developer console?
ps. I'm unsure what this construct is called technically so I just called it an "assigned function".
MyJSObject.createReview = function (c)
In head of page:
if (typeof MyJSObject === "undefined" || !MyJSObject) {var MyJSObject = {};}
MyJSObject.headLoc = document.getElementsByTagName("head").item(0);
MyJSObject.createReview = function (c) {
console.error('createReview called');
MyJSObject.widgetType = c.widgetType;
var a = "https://www.example.com/api/getcompanyreviewdetails/?id=2&callback=MyJSObject.writeReviewsCallback";
var b = document.createElement("script");
b.setAttribute("type", "text/javascript");
b.setAttribute("src", a);
MyJSObject.headLoc.appendChild(b);
};
Then on a button click I call this function, after which I'd expect the "createReview called" message to be printed to the console as an error (I use console.error since there's alreayd a lot of loglines created by other apps and I don't want to have to look for my message. console.log does not show anything either btw):
MyJSObject.createReview({"widgetType":1});
I does appears in your console as an error. bcause it's .error not .log
Maybe you filtered your console for logs and not errors ?
BTW you have an error on this line b.setAttribute("src", a); "a is undefined"
try F12 on this JSFIDDLE
If filter is not the problem, and since it works for me,please try the chrome canary, this happened to me once and was solved on chrome next version.
Are you sure you properly registered a callback to the desired click event?
check that by printing out something there too
$('#buttonToClick').click(function(){
console.log("Check Click");
myJSObject.createReview(..);
});
If you can't find that in the Console it means you are not invoking the createReview method at all
You may try it on a different browser to see if you don't have a bug.
Maybe in your includes, someone overwrote console.log and console.error.
e.g:
console.log = function(){//donothing}
In such case, you should output the function body to your dom to ensure no one altered it.
Idem :
document.getElementById('someJunkDiv').innerHTML = console.log.toString()
Assume I run my Javascript project in a browser and I'm inside a specific module, can I check whether is already message printed to the console ? i.e. read message from the console...
For example I'm inside my js.file inside function want to check if already printed hello world in the console.
jthanto's answer gave me an idea. I don't think it's good practice, but if you must, you can define your own console class:
var MyConsole = function(oldConsole) {
// store all messages ever logged
this.log = [];
// keep a pointer to oldConsole
this.oldConsole = oldConsole;
}
MyConsole.prototype.log = function(args) {
// push the message into log
this.log.push(Array.prototype.join.call(args));
// call oldConsole.log to actually display the message on the console
if (this.oldConsole)
this.oldConsole.log.apply(this.oldConsole, args);
}
// TODO: implement all other console methods in this fashion (apply for all console API methods)
MyConsole.prototype.<method> = function(args) {
if (this.oldConsole)
this.oldConsole.<method>.apply(this.oldConsole, args);
}
// method to check if something was printed
MyConsole.prototype.wasLogged(message) {
return this.log.indexOf(message)!==-1;
}
// replace console with an instance of MyConsole, pointing to the old console
console = new MyConsole(console);
Save it in a file and load it first (right at the top of your tags)
Use it like:
if (console.wasLogged("Hello World"))
doStuffz();
Hope it helps. Mind it's not tested, but should give you some pointers :)
You could always define your own function for "console.logging" one or more messages (if this is what you are doing), and have a boolean in this function to handle this sort of thing.
I would bet it's not "best practice", but it would solve your problem in some degree.
var messageSent = false;
var myConsoleLog = function($strMessage){
if (!messageSent) {
console.log($strMessage);
messageSent = true;
} else {
// Do whatever you feel like
}
};
Of course if you need to check for more cases you will need to alter the function to actually keep track of more messages. :)
Normally it can't be done. Look at Chrome console's API:
https://developer.chrome.com/devtools/docs/console-api
But this experimental Chrome feature can solve your problem: https://developer.chrome.com/extensions/experimental_devtools_console
Unfortunately it looks like other browsers doesn't have tools like this.
This question already has answers here:
Get all javascript errors on page/javascript error handling
(4 answers)
Closed 10 years ago.
I want to create a js code snippet which will run onclick of a button on page. After clicking that button it will find whether the console has some errors? (i.e. if its showing some error in status bar in IE) If it has error then it will show an alert box saying that some js code failed on this page. Otherwise will show msg "Passed"
Is it possible to get list of js errors from within the page?
<button id="button">Bug out</button>
<script>
var myErrors = [],
startTrackingErrors = false;
window.onerror = function (errorMessage, url, lineNumber) {
if (!startTrackingErrors) { return false; }
myErrors.push({
errorMessage : errorMessage,
url : url,
lineNumber : lineNumber
});
return true;
};
document.getElementById('button').click = function() {
startTrackingErrors = true;
// put your buggy code here
// loop through "myErrors" array when done
};
</script>
You could use the 'try' and 'catch' directives
try
{
// code that may have an error
}
catch(e)
{
alert('There was an error: '+e.message);
}
finally
{
alert('Execute this bit anyway');
}
As far as I know, it is not possible to read the console output. You can, however, assign a handler to window.onerror to capture all JavaScript errors, that occur inside a page.
Note that this is not implemented in all browsers. I can't find a compatibility table for it right now, though.
I'm using Casper.js to automate a regular upload. I've managed to upload the file and check if it's valid, but I'd like to parse the table which is returned if there's errors, but I get the error [error] [remote] findAll(): invalid selector provided "[object Object]":Error: SYNTAX_ERR: DOM Exception 12. Here's the relevant part of my code:
casper.then(function() {
if (this.fetchText('.statusMessageContainer').match(/Sorry, the file did not pass validation. Please review the validation errors in the report below/)) {
this.echo("Upload failed!", "ERROR");
errors = this.evaluate(function() {
var errorRows = __utils__.findAll({
type: 'xpath',
path: '//table[#id="uploadTable"]/tr[position()>1]'
});
return Array.prototype.forEach.call(errorRows, function(e) {
return e;
});
});
this.echo(JSON.stringify(errors));
} else {
this.echo("Upload successful", "INFO");
}
});
Any ideas?
While you probably have an XPath syntax error, you must know that you cannot return DOM elements from a closure passed to the evaluate() method; you have to convert your NodeList and HTMLelement instances to some native Javascript types, eg. Arrays, Objects, strings, etc…
Also, there's a convenient getElementsByXPath() method in the ClientUtils module you can use from the __utils__ instance automatically injected in every page your load:
casper.then(function() {
if (this.fetchText('.statusMessageContainer').match(/Sorry, the file did not pass validation. Please review the validation errors in the report below/)) {
this.echo("Upload failed!", "ERROR");
var errors = this.evaluate(function() {
var errorRows = __utils__.getElementsByXPath('//table[#id="uploadTable"]/tr[position()>1]');
return Array.prototype.map.call(errorRows, function(e) {
return e.innerText; // let's get node text instead of HTMLelement!
});
});
this.echo(JSON.stringify(errors));
} else {
this.echo("Upload successful", "INFO");
}
});
You can also use the ClientUtils bookmarklet to test your selectors right within your browser console as well. For example here, click the bookmarklet and execute this in the js console:
__utils__.getElementsByXPath('//table[#id="uploadTable"]/tr[position()>1]')
Then you'll see if your selector is correct (it works by my side — I mean it is syntactically correct).
Well from your error it appears there is something wrong with your selector.
It's setup correctly from what I can see, except for one thing: Try changing '//table[#id="uploadTable"]/tr[position()>1]' to '//table[#id='uploadTable']/tr[position()>1]' (change "" to '')
Other than that, your XPath looks syntactically correct, so I'm not sure why it would qualify as an invalid selector.