Firebug not showing stack trace for errors? - javascript

I have noticed that even with "show stack trace with errors" enabled from the drop down, only errors that occur seem to have traces, but when I do: throw new Error('foo'); I do not see any stack trace for it even though it seems to appear in the console exactly the same way as other errors that occur such as iDoNotExist().
Is there something I am missing?
It also seems that I get the stack trace for calling console.error('foo');. Odd.
It should be noted that stack traces do occur on Webkit Inspector and Opera when doing throw new Error('foo');.

For others landing here :
The issue for me was showStackTrace is set to false by default for Firebug.
Here's how to enable it :
Goto about:config in Firefox
Change the value of the preference extensions.firebug.showStackTrace from false to true (Double-click toggles the value).

I tested this code in Firebug 1.7.1b2 (FF: 4.0.1, on win7) and it shows me stack trace:
function a(){
throw new Error('s');
};
function b(){
a()
}
b();

Have you tried:
var err = new Error();
err.name = 'My custom error';
err.message = 'foo';
throw(err);
Or even (doesn't always work):
throw 'foo';
throw('foo');

Related

How to suppress uncaught exceptions in IE

Exceptions can be suppressed in Chrome and Firefox but none of the approaches work in IE
window.addEventListener("error", function errorHandler(event) {
console.log("exception should be suppressed and not shown in the console");
event.preventDefault();
});
throw "suppress me";
and
window.onerror = function errorHandler() {
console.log("exception should be suppressed and not shown in the console");
return true;
};
throw "suppress me";
You can play with them
https://jsfiddle.net/9uj4xm3g/4/
https://jsfiddle.net/gv0pvy3b/3/
Any ideas?
UPD:
I forgot to clarify what I mean by suppressing. I would like to be able to hide SCRIPT5022 message completely by marking an error as handled.
According to https://msdn.microsoft.com/en-us/library/cc197053.aspx
To suppress the default Windows Internet Explorer error message for
the window event, set the returnValue property of the event object to
true or simply return true in Microsoft JScript.
But as you see this doesn't help with errors logged to the console
The problem here is how you're throwing the exception.
You should be doing the following:
throw new Error("my error");
Here's a reference: https://www.nczonline.net/blog/2009/03/10/the-art-of-throwing-javascript-errors-part-2/

Getting the stack trace of a console message

Sometimes I see stray log statements when I load up my application, and I don't remember how the log statement was called. Is there a way to find the stack trace of a console log message from the Chrome developer tools?
Right now, I wrap console.log with a function that prints the stack trace:
console.log = (function () {
var oldLog = console.log.bind(console);
return function () {
try { throw new Error(); } catch (e) {
oldLog(
e.stack.split('\n')
.slice(2)
.map((line) => line.trim().replace('at', 'from'))
.join('\n')
);
}
oldLog.apply(null, Array.prototype.slice.call(arguments));
};
}());
This will print the stack trace in addition to the log message. For this to be useful, I have to insert this code just before any of my code runs. Is there a way to find out this information from just the console, without having to add this wrap?
I primarily use Chrome developer tools, but I'd be interested if this was possible in any other browser.
Have you tried console.trace()? It is available in Chrome and Firefox. For your use-case, you could alias log to trace.
That said, I usually wrap logger statements in a custom logger function that itself wraps whatever I need to use, but which can be programmatically disabled in production to prevent leaking logs.
EDIT:
There aren't currently any chrome://flags that would let you set that behaviour, but you could do this before your console gets invoked (such as at the top of your minified js): console.log=console.trace;
Which will have this effect, (example in Chrome Canary's console):
> console.log("Hello, Robz");
VM929:2 Hello, Robz
undefined
> console.log = console.trace;
function trace() { [native code] }
> console.log("Hello, Robz");
VM935:2 Hello, Robz
VM935:2 (anonymous function)
VM468:777 InjectedScript._evaluateOn
VM468:710 InjectedScript._evaluateAndWrap
VM468:626 InjectedScript.evaluate
Basically. To show the source of a logging-message was a very bad idea. It leads you to write logging messages that neither belongs to the code nor can be localized without a stack-trace.
How do you work in a Team with it?
hey, i got a `ohoh!`-logging in file abc.js in line 3487!
To understand the problem by inspecting the call-stack means: Hey i do not need a text-message, i do not need a message what exactly is going on, just where.

How can I override/extend ReferenceError in Chrome's JavaScript?

To make debugging easier, I'm capturing all of the console logs in Chrome so that users who submit a feedback entry will also submit all of the logs to our server. When someone encounters a problem in production, I can first and foremost get them back to work so that I can then sit down and more thoroughly go through all of the logs to determine the root cause of whatever issue the user encountered in production.
The technique I use to capture the logs involves overriding console.log so that all text entered in the first argument gets stored in an array while simultaneously invoking the legacy function so that I can still see the logs in the console too.
The problem is when there's the occasional uncaught exception. These aren't included in the uploaded logs, so it's not always clear what caused the problem. So I tried overriding ReferenceError by writing a JavaScript function that takes a function as an argument, then returns a new function that does stuff with it, like storing data in a variable, and then invoking the legacy function as the last step:
function overrideException(legacyFn) {
/** arguments for original fn **/
return function() {
var args = [];
args[0] = arguments[0];
// pass in as arguments to original function and store result to
// prove we overrode the ReferenceError
output = ">> " + legacyFn.apply(this, args).stack;
return legacyFn.apply(this, arguments);
}
}
To test the overrideException function, I ran the following code on the console:
ReferenceError = overrideException(ReferenceError);
Afterwards, I tested the returned function, the new ReferenceError, by manually throwing a ReferenceError:
throw new ReferenceError("YES!! IT WORKS! HAHAHA!");
The resulting output on the console is:
ReferenceError: YES!! IT WORKS! HAHAHA!
And checking the global variable output from the overrideException function shows that it did indeed run:
output
">> ReferenceError: YES!! IT WORKS! HAHAHA!
at ReferenceError (<anonymous>)
at new <anonymous> (<anonymous>:18:35)
at <anonymous>:2:7
at Object.InjectedScript._evaluateOn (<anonymous>:562:39)
at Object.InjectedScript._evaluateAndWrap (<anonymous>:521:52)
at Object.InjectedScript.evaluate (<anonymous>:440:21)"
Now, here's where things start to fall apart. In our code, we're not going to know when an uncaught exception occurs, so I tested it by attempting to run a function that doesn't exist:
ttt();
Which results in:
ReferenceError: ttt is not defined
However, unlike the case where we explicitly throw an error, in this case, the function doesn't fire, and we're left with only the legacy functionality. The contents of the variable output is the same as in the first test.
So the question seems to be this: How do we override the ReferenceError functionality that the JavaScript engine uses to throw errors so that it's the same one we use when we throw a ReferenceError?
Keep in mind that my problem is limited only to Chrome at this time; I'm building a Chrome Packaged app.
I have done quite a bit of research for the same reason: I wanted to log errors and report them.
"Overriding" a native type (whether ReferenceError, String, or Array) is not possible.
Chrome binds these before any Javascript is run, so redefining window.ReferenceError has no effect.
You can extend ReferenceError with something like ReferenceError.prototype.extension = function() { return 0; }, or even override toString (for consistency, try it on the page, not the Dev Tools).
That doesn't help you much.
But not to worry....
(1) Use window.onerror to get file name, 1-indexed line number, and 0-indexed position of uncaught errors, as well as the error itself.
var errorData = [];
onerror = function(message, file, line, position, error) {
errorData.push({message:message, file:file, line:line, position:position, error:error});
};
See the fiddle for an example. Since the OP was Chrome-specific, this has only been tested to work in Chrome.
(2) Because of improvements to (1), this is no longer necessary, but I leave this second technique here for completeness, and since onerror is not guaranteed to work for all errors on all browsers. You will also sometimes see the following:
var errors = [];
function protectedFunction(f) {
return function() {
try {
f.apply(this, arguments);
} catch(e) {
errors.push(e);
throw e;
}
};
}
setTimeout = protectedFunction(setTimeout);
setInterval = protectedFunction(setInterval);
etc...
FYI, all this is very similar to what has been done in the Google Closure Compiler library, in goog.debug, created during Gmail development with the intent of doing exactly this. Of particular interest is goog.debug.ErrorHandler and goog.debug.ErrorReporter.

catching error event message from firefox

I can't find a way to catch the error message under firefox:
window.addEventListener("error", handleException, false);
...
function handleException(e) {
alert(e);
return false;
}
...
<script>
throw new Error('sdasd');
</script>
This enters very well the handleException method however the e parameter is an error event under firefox and I don't know how to get the associated message.
In chrome for instance, I get either the message through e.message because after the error bubbles up to not being caught, there's an automatic error fired at window level (See this fiddle: the final error is "Uncaught") that contains the original error that I raised manually.
So to have the same behaviour under firefox (if you run the fiddle under firefox you'll see that the message is "undefined") I found a workaround consisting in encapsulating an error raising function to setup a manual "last error" architecture:
function err(I_sText) {
g_lastManualError = new Error(I_sText);
throw g_lastManualError; //this variable is global so I can get the message from anywhere
}
So instead of doing throw new Error(..) I only call err(..). That works, at least for user defined exceptions, which are my biggest concern. In my handler handleException I'm consulting the global variable.
Do you know how I could do otherwise? I'm not happy with this solution.
Thank you,
S.
I modified your code a little as a demo:
function handleException(e) {
console.log(e);
alert(e);
return false;
}
window.addEventListener("error", handleException, false);
try {
throw new Error('sdasd');
}
catch (e) {
console.log(e)
}
console.log('after exception 1');
throw new Error('foo');
console.log('after exception 2');
Running this code (in Firebug) showed me this:
Error: sdasd
[Break On This Error]
Filtered chrome url chrome://firebug/content/console/commandLineExposed.js
comman...osed.js (line 175)
<System>
after exception 1
"Error: foo ` throw new Error('foo');` #14"
If you're trying to catch an error, use try {...} catch { ...}. It looks like you're just binding to an error event, so the exception you're throwing will still propagate up to window and tell the JS engine to halt. Run this code in Chrome, you'll see that you never see "after exception 2", but you will see "after exception 1".
The purpose of exceptions (created by throw) is to stop code execution unless there's code made to handle that particular exception. You can see an example on the MDN page for try-catch
Edit: it just occurred to me that you might be trying to catch a jQuery error event. If this is the case, your event binding is correct but you shouldn't be testing it with throw
Edit 2: I should've noticed this sooner, but you're trying to listen for a DOM error event with window.addEventListener. Error events will not break execution. Exceptions do.
Replace your code throw new Error('sdasd'); with this code:
var customEvent = new CustomEvent('error')
window.dispatchEvent(customEvent);
That should solve your problem. I used the MDN page on custom events as a reference.

How to log exceptions in JavaScript

As a C# developer I'm used to the following style of exception handling:
try
{
throw SomeException("hahahaha!");
}
catch (Exception ex)
{
Log(ex.ToString());
}
Output
------
SomeNamespace.SomeException: hahahaha!
at ConsoleApplication1.Main() in ConsoleApplication1\Program.cs:line 27
Its really simple, and yet tells me everything I need to know about what the exception was and where it was.
How do I achieve the equivalent thing in JavaScript where the exception object itself might just be a string. I really want to be able to know the exact line of code where the exception happened, however the following code doesn't log anything useful at all:
try
{
var WshShell = new ActiveXObject("WScript.Shell");
return WshShell.RegRead("HKEY_LOCAL_MACHINE\\Some\\Invalid\\Location");
}
catch (ex)
{
Log("Caught exception: " + ex);
}
Output
------
Caught exception: [object Error]
EDIT (again): Just to clarify, this is for internal application that makes heavy use of JavaScript. I'm after a way of extracting useful information from JavaScript errors that may be caught in the production system - I already have a logging mechanism, just want a way of getting a sensible string to log.
You don't specify if you are working in the browser or the server. If it's the former, there is a new console.error method and e.stack property:
try {
// do some crazy stuff
} catch (e) {
console.error(e, e.stack);
}
Please keep in mind that error will work on Firefox and Chrome, but it's not standard. A quick example that will downgrade to console.log and log e if there is no e.stack:
try {
// do some crazy stuff
} catch (e) {
(console.error || console.log).call(console, e.stack || e);
}
As Eldar points out, you can use e.message to get the message of the exception. However, in Chrome, Firefox and IE10+, you can also get the stack trace using e.stack. The stack trace will include the file and line number of the exception.
So to assemble a string with exception info, you would write something like this:
var exmsg = "";
if (e.message) {
exmsg += e.message;
}
if (e.stack) {
exmsg += ' | stack: ' + e.stack;
}
Note that you will only get a stack trace if
the exception was thrown by the browser (such as in response to a
syntax error);
the exception object is an Error object or has the Error object as its prototype.
So just throwing a string (throw 'Exception!!') won't give you a stack trace.
To take this a bit further, to catch all uncaught exceptions, you would use a window.onerror handler (similar to .Net Application_Error handler in global.asax). The drawback of this used to be (and mostly still is) that this wouldn't give you access to the actual exception object, so you couldn't get the stack trace. You'd only get the message, url and line number.
Recently, the standard has been extended to give you the column (great for minified files) and the exception object as well:
http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#errorevent
Right now (April 2014), only Chrome 32 implements all this. IE10+ gives you the column but not the exception object. Firefox 28 still only gives you message, url and line number. Hopefully, this will improve soon. I've written about this for the JSNLog project, at:
http://jsnlog.com/Documentation/GetStartedLogging/ExceptionLogging
(disclaimer: I am the author of JSNLog and jsnlog.com)
Secondly, the .Net Exception object supports inner exceptions. It also has a Data property so you can attach key value pairs with for example variable values. I sort of missed that in JavaScript Error object, so I created my own Exception object, also as part of the JSNLog project. It is in the jsnlog.js file in the jsnlog.js Github project (https://github.com/mperdeck/jsnlog.js).
Description is at:
http://jsnlog.com/Documentation/JSNLogJs/Exception
Finally a shameless plug - the JSNLog project I'm working on lets you insert loggers in your JavaScript, and automatically inserts the log messages in your existing server side log. So to log JavaScript exceptions with their stack traces to your server side log, you only need to write:
try {
...
} catch (e) {
JL().fatalException("something went wrong!", e);
}
You can use almost in the same manner ie.
try
{
throw new Error("hahahaha!");
}
catch (e)
{
alert(e.message)
}
But if you want to get line number and filename where error is thrown i suppose there is no crossbrowser solution. Message and name are the only standart properties of Error object. In mozilla you have also lineNumber and fileName properties.
I'm not sure whether or not it is cross browser or if it's what you are looking for, but I suggest you try:
window.onerror = function (err, file, line) {
logError('The following error occurred: ' +
err + '\nIn file: ' + file + '\nOn line: ' + line);
return true;
}
I had a similar problem.
Using console.table(error); worked well for me.
It displays information in a table, and also lets me expand/collapse to see more details.
It is almost identical, see the manual: https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Exception_Handling_Statements/try...catch_Statement
You can use logging tools like Yahoo! UI Library - Logger to log the errors/informative messages.
I wrote a handy function for it
const logError = (e: any) => {
if (console.error) console.error(e, e.stack);
else console.log(e)
}
The modern best practice (as I understand it) is to log the error as a separate argument to console.error (or console.log, console.warn, etc...)
try {
maybeThrows()
} catch (e) {
console.error('it threw', e);
}
Trying out this approach in practice:
try {
throw Error('err') // Error object
} catch (e) {
console.error('it threw', e); // it threw Error: err
}
try {
throw 'up' // not an error object
} catch (e) {
console.error('it threw', e); // it threw up
}
I ran the above in Chrome, and Node v16. Note that node did not include a stack trace for throw 'up', but did for the proper error. Chrome included the stack for both.

Categories