How to get JavaScript caller function line number and caller source URL

Viewed 130490

I am using the following for getting the JavaScript caller function name:

var callerFunc = arguments.callee.caller.toString();
callerFuncName = (callerFunc.substring(callerFunc.indexOf("function") + 8, callerFunc.indexOf("(")) || "anoynmous")

Is there a way to discover the line number from which the method was called?

Also, is there a way to get the name of the JavaScript file the method was called from? Or the source URL?

17 Answers

I realize this is an old question but there is now a method called console.trace("Message") that will show you the line number and the chain of method calls that led to the log along with the message you pass it. More info on javascript logging tricks are available here at freecodecamp and this medium blog post

the following code works for me in Mozilla and Chrome.

Its log function that shows the file's name and the line of the caller.

log: function (arg) {
    var toPrint = [];
    for (var i = 0; i < arguments.length; ++i) {
        toPrint.push(arguments[i]);
    }

    function getErrorObject(){
        try { throw Error('') } catch(err) { return err; }
    }

    var err = getErrorObject(),
        caller;

    if ($.browser.mozilla) {
        caller = err.stack.split("\n")[2];
    } else {
        caller = err.stack.split("\n")[4];
    }

    var index = caller.indexOf('.js');

    var str = caller.substr(0, index + 3);
    index = str.lastIndexOf('/');
    str = str.substr(index + 1, str.length);

    var info = "\t\tFile: " + str;

    if ($.browser.mozilla) {
        str = caller;
    } else {
        index = caller.lastIndexOf(':');
        str = caller.substr(0, index);
    }
    index = str.lastIndexOf(':');
    str = str.substr(index + 1, str.length);
    info += " Line: " + str;
    toPrint.push(info);

    console.log.apply(console, toPrint);
}

If you need something that is very complete and accurate, for v8 (meaning NodeJS and Chrome) there is the stack-trace package, which worked for me:

https://www.npmjs.com/package/stack-trace

This has several advantages: being able to produce deep stack-traces, being able to traverse async calls, and providing the full URL of scripts at every stack-frame.

You can find more information about the v8 stack-track API here.

If you need something that works in more browsers, there is this package:

https://www.npmjs.com/package/stacktrace-js

This library parses the formatted stack-trace strings you normally see in the devtools console, which means it only has access to information that actually appears in a formatted stack-track - unlike the v8 API, you can't get (among other things) the full URL of the script in a stack-frame.

Note that parsing a formatted stack-trace is a somewhat fragile approach, as this formatting could change in the browsers, which would break your app.

As far as I know, there is no safer bet for something cross-browser - if you need something fast, accurate and complete that works in all browsers, you're pretty much out of luck.

It was easier in the past, but at this time with browser updates:

This is the safe Multi Browser Solution

<!DOCTYPE html>
<html lang="en">
<head>
    <script>
        var lastErr;
        function errHand(e) {
            lastErr = e;
            switch (e.target.nodeName) {
                case 'SCRIPT':
                    alert('script not found: ' + e.srcElement.src);
                    break;
                case 'LINK':
                    alert('css not found: ' + e.srcElement.href);
            }
            return false;
        }
        window.onerror = function (msg, url, lineNo, columnNo, error) {
            alert(msg + ' - ' + url + ' - ' + lineNo + ' - ' + columnNo);
            return false;
        }
    </script>
    <script src="http://22.com/k.js" onerror="errHand(event)"></script>
    <link rel="stylesheet" href="http://22.com/k.css" onerror="errHand(event)" type="text/css" />
</head>
<body>
    <script>
        not_exist_function();
    </script>
</body>
</html>
  1. Dont try to override or read console auto generated error logs by browser, Not work at this time but in the past it was happened
  2. For control loading each external linked css/js/etc use onerror event property innertag
  3. For control inline/loaded scripts use window.onerror
  4. Place error handle functions in the top of your html code
  5. To develop this code for other special tags like "include" set onerror inline event like step 2 and after fire error use console.log(lastErr) to see error object fields
  6. If you have an error in source of attached js file, then window.onerror fetch the complete log just when the js have same origin host with the main html file, if you test this situation on local with no host then the logs not be complete because of the local-no-host environment not known as same origin
  7. For send Request error handling like Ajax/Websocket its better use their built-in error handle functions

For NodeJS - Global Error Handling Solution

process.on('uncaughtException', function (err) {
    console.error('uncaughtException:\n' + err.stack + '\n');
})

This is very useful, Because it will show up you errors that exist but dont break your main program process.

Related