source

예외 발생 시 JavaScript 스택트레이스를 취득하려면 어떻게 해야 하나요?

gigabyte 2022. 10. 20. 21:52
반응형

예외 발생 시 JavaScript 스택트레이스를 취득하려면 어떻게 해야 하나요?

JavaScript 예외:throw "AArrggg"(Firebug 등으로) 스택트레이스를 취득하려면 어떻게 해야 하나요?지금은 그 메시지를 알 것 같아요.

edit: 아래 많은 사람들이 올린 것처럼 JavaScript 예외에 대한 스택트레이스를 얻을 수 있는데 예외에 대한 스택트레이스를 취득하고 싶습니다.예를 들어 다음과 같습니다.

function foo() {
    bar(2);
}
function bar(n) {
    if (n < 2)
        throw "Oh no! 'n' is too small!"
    bar(n-1);
}

foo이 트레이스에는, 「스택 트레이스」에의 됩니다.foo,bar,bar.

편집 2 (2017):

과 같이 호출할 수 .console.trace(); )(MDN 참조

편집 1(2013):

와 같이 더 좋은 간단한)은 '나'를 하는 입니다.stack의 property의 Error다음과 같이 합니다.

function stackTrace() {
    var err = new Error();
    return err.stack;
}

그러면 다음과 같은 출력이 생성됩니다.

DBX.Utils.stackTrace@http://localhost:49573/assets/js/scripts.js:44
DBX.Console.Debug@http://localhost:49573/assets/js/scripts.js:9
.success@http://localhost:49573/:462
x.Callbacks/c@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
x.Callbacks/p.fireWith@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
k@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6
.send/r@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6

호출 함수의 이름과 URL, 호출 함수 등을 지정합니다.

오리지널 (2009) :

스니펫의 수정 버전은 다음 사항에 도움이 될 수 있습니다.

function stacktrace() { 
  function st2(f) {
    return !f ? [] : 
        st2(f.caller).concat([f.toString().split('(')[0].substring(9) + '(' + f.arguments.join(',') + ')']);
  }
  return st2(arguments.callee.caller);
}

파이어폭스만 아니라 V8을 사용하는 및 는 V8을 스택 를 얻을 수 있는 를 갖추고 .stack의 of의 Error★★★★★★★★★★★★★★★★★★:

    try {
        // Code throwing an exception
        throw new Error();
    } catch(e) {
        console.log(e.stack);
    }

자세한 내용은 V8 매뉴얼을 참조하십시오.

Firefox에서는 예외를 둘 필요가 없는 것 같습니다.해도 충분하다

e = new Error();
console.log(e.stack);

Firebug가 있는 경우 스크립트 탭에 모든 오류에 대한 중단 옵션이 있습니다.스크립트가 중단점에 도달하면 firebug의 스택 창을 볼 수 있습니다.

스크린샷

번째 된 바와 좋은은 '어느 쪽인가'를 입니다.stack의 property의 Error다음과 같이 합니다.

function stackTrace() {
    var err = new Error();
    return err.stack;
}

그러면 다음과 같은 출력이 생성됩니다.

DBX.Utils.stackTrace@http://localhost:49573/assets/js/scripts.js:44
DBX.Console.Debug@http://localhost:49573/assets/js/scripts.js:9
.success@http://localhost:49573/:462
x.Callbacks/c@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
x.Callbacks/p.fireWith@http://localhost:49573/assets/js/jquery-1.10.2.min.js:4
k@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6
.send/r@http://localhost:49573/assets/js/jquery-1.10.2.min.js:6

발신 기능의 이름과 URL 및 회선 번호, 발신 기능등을 지정합니다.

저는 현재 진행 중인 프로젝트를 위해 고안한 매우 정교하고 예쁜 솔루션이 있으며, 일반화하기 위해 조금 추출하여 재작업했습니다.여기 있습니다.

(function(context){
    // Only global namespace.
    var Console = {
        //Settings
        settings: {
            debug: {
                alwaysShowURL: false,
                enabled: true,
                showInfo: true
            },
            stackTrace: {
                enabled: true,
                collapsed: true,
                ignoreDebugFuncs: true,
                spacing: false
            }
        }
    };

    // String formatting prototype function.
    if (!String.prototype.format) {
        String.prototype.format = function () {
            var s = this.toString(),
                args = typeof arguments[0],
                args = (("string" == args || "number" == args) ? arguments : arguments[0]);
            if (!arguments.length)
                return s;
            for (arg in args)
                s = s.replace(RegExp("\\{" + arg + "\\}", "gi"), args[arg]);
            return s;
        }
    }

    // String repeating prototype function.
    if (!String.prototype.times) {
        String.prototype.times = function () {
            var s = this.toString(),
                tempStr = "",
                times = arguments[0];
            if (!arguments.length)
                return s;
            for (var i = 0; i < times; i++)
                tempStr += s;
            return tempStr;
        }
    }

    // Commonly used functions
    Console.debug = function () {
        if (Console.settings.debug.enabled) {
            var args = ((typeof arguments !== 'undefined') ? Array.prototype.slice.call(arguments, 0) : []),
                sUA = navigator.userAgent,
                currentBrowser = {
                    firefox: /firefox/gi.test(sUA),
                    webkit: /webkit/gi.test(sUA),
                },
                aLines = Console.stackTrace().split("\n"),
                aCurrentLine,
                iCurrIndex = ((currentBrowser.webkit) ? 3 : 2),
                sCssBlack = "color:black;",
                sCssFormat = "color:{0}; font-weight:bold;",
                sLines = "";

            if (currentBrowser.firefox)
                aCurrentLine = aLines[iCurrIndex].replace(/(.*):/, "$1@").split("@");
            else if (currentBrowser.webkit)
                aCurrentLine = aLines[iCurrIndex].replace("at ", "").replace(")", "").replace(/( \()/gi, "@").replace(/(.*):(\d*):(\d*)/, "$1@$2@$3").split("@");

            // Show info if the setting is true and there's no extra trace (would be kind of pointless).
            if (Console.settings.debug.showInfo && !Console.settings.stackTrace.enabled) {
                var sFunc = aCurrentLine[0].trim(),
                    sURL = aCurrentLine[1].trim(),
                    sURL = ((!Console.settings.debug.alwaysShowURL && context.location.href == sURL) ? "this page" : sURL),
                    sLine = aCurrentLine[2].trim(),
                    sCol;

                if (currentBrowser.webkit)
                    sCol = aCurrentLine[3].trim();

                console.info("%cOn line %c{0}%c{1}%c{2}%c of %c{3}%c inside the %c{4}%c function:".format(sLine, ((currentBrowser.webkit) ? ", column " : ""), ((currentBrowser.webkit) ? sCol : ""), sURL, sFunc),
                             sCssBlack, sCssFormat.format("red"),
                             sCssBlack, sCssFormat.format("purple"),
                             sCssBlack, sCssFormat.format("green"),
                             sCssBlack, sCssFormat.format("blue"),
                             sCssBlack);
            }

            // If the setting permits, get rid of the two obvious debug functions (Console.debug and Console.stackTrace).
            if (Console.settings.stackTrace.ignoreDebugFuncs) {
                // In WebKit (Chrome at least), there's an extra line at the top that says "Error" so adjust for this.
                if (currentBrowser.webkit)
                    aLines.shift();
                aLines.shift();
                aLines.shift();
            }

            sLines = aLines.join(((Console.settings.stackTrace.spacing) ? "\n\n" : "\n")).trim();

            trace = typeof trace !== 'undefined' ? trace : true;
            if (typeof console !== "undefined") {
                for (var arg in args)
                    console.debug(args[arg]);

                if (Console.settings.stackTrace.enabled) {
                    var sCss = "color:red; font-weight: bold;",
                        sTitle = "%c Stack Trace" + " ".times(70);

                    if (Console.settings.stackTrace.collapsed)
                        console.groupCollapsed(sTitle, sCss);
                    else
                        console.group(sTitle, sCss);

                    console.debug("%c" + sLines, "color: #666666; font-style: italic;");

                    console.groupEnd();
                }
            }
        }
    }
    Console.stackTrace = function () {
        var err = new Error();
        return err.stack;
    }

    context.Console = Console;
})(window);

GitHub(현재 v1.2)에서 확인하세요!다음과 같이 사용할 수 있습니다.Console.debug("Whatever"); 이 설정은 의 에 따라 달라집니다Console출력과 스택트레이스를 인쇄합니다(또는 단순한 정보 또는 추가 정보는 전혀 없습니다).하다

Console.js

의 놀아주세요.Console오! ! 끌 수 .배선의 행 사이에 간격을 추가하고 완전히 끌 수 있습니다. .Console.tracefalse:

추적 없음

첫 끌 " " " " " " ) 。Console.settings.debug.showInfo로로 합니다.false을 완전히 합니다 "set "set "disable" "set "disable").Console.settings.debug.enabled로로 합니다.false그냥 놔두면 아무 소용도 없을 거야

사용할 수 있는 것은 없는 것 같습니다만, 자신의 것을 굴리는 예는 많이 있습니다.

할 수 .stack )stacktraceError★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ 중요한 건, 꼭 하세요, 사용법은 사용하세요.throw new Error(string)(대신 새로운 을 잊지 마세요)throw string.

예제:

try {
    0++;
} catch (e) {
    var myStackTrace = e.stack || e.stacktrace || "";
}

브라우저를 하면 Chrome을 사용할 수 .console.trace방법: https://developer.chrome.com/devtools/docs/console-api#consoletraceobject

이를 통해 최신 Chrome, Opera, Firefox 및 IE10+에 대한 스택 트레이스(스트링 배열)가 제공됩니다.

function getStackTrace () {

  var stack;

  try {
    throw new Error('');
  }
  catch (error) {
    stack = error.stack || '';
  }

  stack = stack.split('\n').map(function (line) { return line.trim(); });
  return stack.splice(stack[0] == 'Error' ? 2 : 1);
}

사용방법:

console.log(getStackTrace().join('\n'));

스택에서 자체 콜과 Chrome 및 Firefox(IE는 제외)에서 사용되는 제목 "Error"는 제외됩니다.

오래된 브라우저에서는 크래시가 발생하지 않고 빈 어레이만 반환됩니다.범용 솔루션이 더 필요한 경우 stacktrace.js를 참조하십시오.서포트되고 있는 브라우저의 리스트는 매우 인상적이지만, 그 작은 태스크에는 매우 큰 것입니다.모든 의존관계를 포함한 37Kb의 최소 텍스트입니다.

특정 버전?)IE(특정 버전)에 입력하기 있을 필요가 있습니다.stack , 다시 돌아오지 않도록 합니다.undefinedIE 는 、 [ ]

function stackTrace() {
  try {
    var err = new Error();
    throw err;
  } catch (err) {
    return err.stack;
  }
}

메모 1: 이러한 조작은 디버깅 시에만 실행해 주세요.실시간 중에는 특히 콜이 빈번한 경우는 무효로 해 주세요.메모 2: 일부 브라우저에서는 동작하지 않을 수 있지만 FF 및 IE 11에서는 동작하는 것 같습니다.이것은, 제 요구에 딱 맞습니다.

Firebug에서 실제 스택트레이스를 얻는 방법 중 하나는 정의되지 않은 함수를 호출하는 것과 같은 실제 오류를 생성하는 것입니다.

function foo(b){
  if (typeof b !== 'string'){
    // undefined Error type to get the call stack
    throw new ChuckNorrisError("Chuck Norris catches you.");
  }
}

function bar(a){
  foo(a);
}

foo(123);

「」를 사용합니다.console.error()에 '아예'가 붙습니다.throw「 」이래의 console.error()에 스택 트레이스를 나타냅니다.

이 폴리필 코드는 최신(2017년) 브라우저(IE11, Opera, Chrome, FireFox, Yandex)에서 작동합니다.

printStackTrace: function () {
    var err = new Error();
    var stack = err.stack || /*old opera*/ err.stacktrace || ( /*IE11*/ console.trace ? console.trace() : "no stack info");
    return stack;
}

기타 답변:

function stackTrace() {
  var err = new Error();
  return err.stack;
}

IE 11에서는 동작하지 않습니다!

arguments.callee.caller 사용 - 브라우저에서는 엄밀한 모드로 동작하지 않습니다.

Google Chrome(버전 19.0 이상)에서는 예외를 던지는 것만으로 완벽하게 작동합니다.예를 들어 다음과 같습니다.

/* file: code.js, line numbers shown */

188: function fa() {
189:    console.log('executing fa...');
190:    fb();
191: }
192:
193: function fb() {
194:    console.log('executing fb...');
195:    fc()
196: }
197:
198: function fc() {
199:    console.log('executing fc...');
200:    throw 'error in fc...'
201: }
202:
203: fa();

는 브라우저 콘솔 출력에 스택트레이스를 표시합니다.

executing fa...                         code.js:189
executing fb...                         code.js:194
executing fc...                         cdoe.js:199
/* this is your stack trace */
Uncaught error in fc...                 code.js:200
    fc                                  code.js:200
    fb                                  code.js:195
    fa                                  code.js:190
    (anonymous function)                code.js:203

이게 도움이 됐으면 좋겠다.

기능:

function print_call_stack(err) {
    var stack = err.stack;
    console.error(stack);
}

사용 사례:

     try{
         aaa.bbb;//error throw here
     }
     catch (err){
         print_call_stack(err); 
     }
<script type="text/javascript"
src="https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.js"></script>
<script type="text/javascript">
    try {
        // error producing code
    } catch(e) {
        var trace = printStackTrace({e: e});
        alert('Error!\n' + 'Message: ' + e.message + '\nStack trace:\n' + trace.join('\n'));
        // do something else with error
    }
</script>

이 스크립트는 오류를 표시합니다.

function stacktrace(){
  return (new Error()).stack.split('\n').reverse().slice(0,-2).reverse().join('\n');
}

엣지 2021의 경우:

console.groupCollapsed('jjjjjjjjjjjjjjjjj')
    console.trace()
    try {
        throw "kuku"
    } catch(e) {
        console.log(e.stack)
    }
console.groupEnd()
traceUntillMe()

그리고 넌 내 친구다.

파티에는 다소 늦었지만, arguments.callee가 사용 가능한 경우 자동검출하고, 없으면 새로운 Error().stack을 사용하는 다른 솔루션이 있습니다.크롬, 사파리 및 파이어폭스에서 테스트 완료.

2개의 베리안트: stackFN(n)은 직접 발신자에서 떨어진 함수n의 이름을 나타내고 stackArray()는 배열을 제공합니다.stackArray()[0]는 직접 발신자가 됩니다.

http://jsfiddle.net/qcP9y/6/에서 시험해 보세요.

// returns the name of the function at caller-N
// stackFN()  = the immediate caller to stackFN
// stackFN(0) = the immediate caller to stackFN
// stackFN(1) = the caller to stackFN's caller
// stackFN(2) = and so on
// eg console.log(stackFN(),JSON.stringify(arguments),"called by",stackFN(1),"returns",retval);
function stackFN(n) {
    var r = n ? n : 0, f = arguments.callee,avail=typeof f === "function",
        s2,s = avail ? false : new Error().stack;
    if (s) {
        var tl=function(x) { s = s.substr(s.indexOf(x) + x.length);},
        tr = function (x) {s = s.substr(0, s.indexOf(x) - x.length);};
        while (r-- >= 0) {
            tl(")");
        }
        tl(" at ");
        tr("(");
        return s;
    } else {
        if (!avail) return null;
        s = "f = arguments.callee"
        while (r>=0) {
            s+=".caller";
            r--;   
        }
        eval(s);
        return f.toString().split("(")[0].trim().split(" ")[1];
    }
}
// same as stackFN() but returns an array so you can work iterate or whatever.
function stackArray() {
    var res=[],f = arguments.callee,avail=typeof f === "function",
        s2,s = avail ? false : new Error().stack;
    if (s) {
        var tl=function(x) { s = s.substr(s.indexOf(x) + x.length);},
        tr = function (x) {s = s.substr(0, s.indexOf(x) - x.length);};
        while (s.indexOf(")")>=0) {
            tl(")");
            s2= ""+s;
            tl(" at ");
            tr("(");
            res.push(s);
            s=""+s2;
        }
    } else {
        if (!avail) return null;
        s = "f = arguments.callee.caller"
        eval(s);
        while (f) {
            res.push(f.toString().split("(")[0].trim().split(" ")[1]);
            s+=".caller";
            eval(s);
        }
    }
    return res;
}


function apple_makes_stuff() {
    var retval = "iPhones";
    var stk = stackArray();

    console.log("function ",stk[0]+"() was called by",stk[1]+"()");
    console.log(stk);
    console.log(stackFN(),JSON.stringify(arguments),"called by",stackFN(1),"returns",retval);
    return retval;
}



function apple_makes (){
    return apple_makes_stuff("really nice stuff");
}

function apple () {
    return apple_makes();
}

   apple();

이 라이브러리는 http://www.stacktracejs.com/ 에서 사용할 수 있습니다.아주 맛이 있습니다.

매뉴얼에서

또한 IE 또는 Safari 5에서 사용할 수 없는 스택 트레이스를 얻기 위해 자신의 오류를 입력할 수도 있습니다.

<script type="text/javascript" src="https://rawgithub.com/stacktracejs/stacktrace.js/master/stacktrace.js"></script>
<script type="text/javascript">
    try {
        // error producing code
    } catch(e) {
        var trace = printStackTrace({e: e});
        alert('Error!\n' + 'Message: ' + e.message + '\nStack trace:\n' + trace.join('\n'));
        // do something else with error
    }
</script>

다음은 최고의 퍼포먼스(IE 6+)와 최대 호환성을 제공하는 답변입니다.IE 6과의 호환성!

    function stacktrace( log_result ) {
    	var trace_result;
    // IE 6 through 9 compatibility
    // this is NOT an all-around solution because
    // the callee property of arguments is depredicated
    /*@cc_on
    	// theese fancy conditinals make this code only run in IE
    	trace_result = (function st2(fTmp) {
    		// credit to Eugene for this part of the code
    		return !fTmp ? [] :
    			st2(fTmp.caller).concat([fTmp.toString().split('(')[0].substring(9) + '(' + fTmp.arguments.join(',') + ')']);
    	})(arguments.callee.caller);
    	if (log_result) // the ancient way to log to the console
    		Debug.write( trace_result );
    	return trace_result;
    @*/
    	console = console || Console;	// just in case
    	if (!(console && console.trace) || !log_result){
    		// for better performance in IE 10
    		var STerror=new Error();
    		var unformated=(STerror.stack || STerror.stacktrace);
    		trace_result = "\u25BC console.trace" + unformated.substring(unformated.indexOf('\n',unformated.indexOf('\n'))); 
    	} else {
    		// IE 11+ and everyone else compatibility
    		trace_result = console.trace();
    	}
    	if (log_result)
    		console.log( trace_result );
    	
    	return trace_result;
    }
// test code
(function testfunc(){
	document.write( "<pre>" + stacktrace( false ) + "</pre>" );
})();

그냥 해봐

throw new Error('some error here')

이것은 Chrome에 매우 적합합니다.

여기에 이미지 설명 입력

파이어폭스에서 스택트레이스를 취득하는 것은 IE에서 취득하는 것보다 간단합니다만, 기본적으로 다음과 같습니다.

문제가 있는 코드를 테스트/캐치 블록에 넣습니다.

try {
    // some code that doesn't work
    var t = null;
    var n = t.not_a_value;
}
    catch(e) {
}

"error" 객체의 내용을 검토하는 경우 다음 필드가 포함됩니다.

e.fileName : 문제가 발생한 소스 파일/페이지 e.lineNumber : 문제가 발생한 파일/페이지 행 번호.message : 발생한 오류 유형을 설명하는 간단한 메시지 e.name : 위의 예에서는 발생한 오류 유형이 'TypeError' e.stack : i를 제외한 스택트레이스가 포함됩니다.

이게 도움이 됐으면 좋겠어요.

IE11에서 Smartgwt의 무한 재귀에 대해 조사해야 했기 때문에 자세히 조사하기 위해서는 스택 트레이스가 필요했습니다.개발 콘솔그렇게 하면 복제가 더 어려웠기 때문입니다.
자바스크립트

try{ null.toString(); } catch(e) { alert(e.stack); }

- 우리가 단 한 .stack★★★★★★★★★★★★★★★★★★★★★★★!에러 핸들러에서 할 수 있는 가장 나쁜 것은 존재하지 않는 것을 호출하기 때문에 에러를 발생시키는 것입니다.

남들이 말했듯이stack는 IE9 사용할 수 .

예기치 않은 에러를 로그에 기록하면 스택트레이스는 매우 중요합니다.최대한의 서포트를 얻기 위해서, 우선, 다음의 유무를 확인합니다.Error.prototype.stack존재하며 함수입니다.그렇다면 사용해도 안전합니다.error.stack

        window.onerror = function (message: string, filename?: string, line?: number, 
                                   col?: number, error?: Error)
        {
            // always wrap error handling in a try catch
            try 
            {
                // get the stack trace, and if not supported make our own the best we can
                var msg = (typeof Error.prototype.stack == 'function') ? error.stack : 
                          "NO-STACK " + filename + ' ' + line + ':' + col + ' + message;

                // log errors here or whatever you're planning on doing
                alert(msg);
            }
            catch (err)
            {

            }
        };

편집: 다음 날짜 이후부터stack는 속성이며 오래된 브라우저에서도 안전하게 호출할 수 있는 메서드가 아닙니다.는 아직 Error.prototype전에는 나를 위해 일했지만 지금은 그렇지 않다 - 그래서 무슨 일이 일어나고 있는지 모르겠다.

「」를 사용합니다.console.error(e.stack)파이어폭스 크롬메시지에 중요한 정보가 포함되어 있는 경우, 이것은 나쁜 서프라이즈가 될 수 있습니다.이치노

언급URL : https://stackoverflow.com/questions/591857/how-can-i-get-a-javascript-stack-trace-when-i-throw-an-exception

반응형