예외를 던질 때 JavaScript 스택 추적을 어떻게 얻을 수 있습니까?
JavaScript 예외를 직접 발생시키는 경우 (예 throw "AArrggg"
:) 스택 추적을 얻는 방법 (Firebug 또는 기타) 바로 지금 메시지를 받았습니다.
편집 : 아래 많은 사람들이 게시 한 것처럼, 그것은을위한 스택 추적을 얻을 수 있습니다 자바 스크립트 예외를 하지만 난에 대한 스택 추적을 얻고 싶은 내 예외. 예를 들면 다음과 같습니다.
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
속성 을 사용하는 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을 사용하는 다른 브라우저)과 Firefox에는 Error 객체 의 스택 속성을 통해 스택 추적을 가져 오는 편리한 인터페이스가 있습니다.
try {
// Code throwing an exception
} catch(e) {
console.log(e.stack);
}
그것은 당신이 던지는 예외뿐만 아니라 기본 예외에도 적용됩니다. (어쨌든 모범 사례 인 Error 클래스를 사용하는 것으로 간주됩니다).
V8 문서에 대한 세부 사항 참조
Firefox에서는 예외를 던질 필요가없는 것 같습니다. 충분하다
e = new Error();
console.log(e.stack);
방화범이 있으면 스크립트 탭에 모든 오류에 대한 휴식 옵션이 있습니다. 스크립트가 중단 점에 도달하면 Firebug의 스택 창을 볼 수 있습니다.
원래 질문에 대한 의견에서 지적한 바와 같이 좋은 (그리고 간단한) 해결책 stack
은 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
개체 의 설정을 가지고 놀아 보십시오! 트레이스 라인 사이에 간격을 추가하고 완전히 끌 수 있습니다. 여기에 Console.trace
설정되어 있습니다 false
:
당신도 같이 정보의 첫 번째 비트 (설정 해제 할 수 있습니다 Console.settings.debug.showInfo
에 false
) 또는 완전히 비활성화 디버깅 (설정 Console.settings.debug.enabled
에를 false
다시 디버그 문을 주석 필요가 없습니다 그래서)! 그것들을 그대로두면 아무것도하지 않습니다.
나는 당신이 사용할 수있는 것이 내장되어 있다고 생각하지 않지만 나는 사람들이 자신을 굴리는 많은 예를 찾았습니다.
인스턴스를 던지더라도 인스턴스 의 stack
( stacktrace
Opera에서) 속성에 액세스 할 수 있습니다 Error
. 문제는 반드시 사용해야합니다 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
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()
이것은 현대 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는 아님)를 제외합니다.
구형 브라우저에서는 충돌하지 않고 빈 배열을 반환합니다. 보다 보편적 인 솔루션이 필요한 경우 stacktrace.js를보십시오 . 지원되는 브라우저 목록은 정말 인상적이지만 내 생각에 작은 작업에는 매우 큽니다. 모든 종속성을 포함하여 37Kb의 축소 된 텍스트.
Eugene의 답변에 대한 업데이트 : IE (특정 버전?)가 stack
속성 을 채우려면 오류 객체가 발생해야합니다 . 다음은 현재 예제보다 잘 작동 undefined
하며 IE에있을 때 반환하지 않아야합니다 .
function stackTrace() {
try {
var err = new Error();
throw err;
} catch (err) {
return err.stack;
}
}
참고 1 : 이런 종류의 작업은 디버깅 할 때만 수행해야하며, 특히 자주 호출되는 경우에는 실시간으로 사용하지 않도록 설정해야합니다. 참고 2 : 이것은 모든 브라우저에서 작동하지는 않지만 FF 및 IE 11에서는 작동하는 것으로 보입니다.
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
이 도움을 바랍니다.
<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 print_call_stack(err) {
var stack = err.stack;
console.error(stack);
}
사용 사례 :
try{
aaa.bbb;//error throw here
}
catch (err){
print_call_stack(err);
}
이 폴리 필 코드는 최신 (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 사용 -모든 브라우저에서 엄격 모드로 작동하지 않습니다!
파티에 늦었지만, 여기에 arguments.callee를 사용할 수 있는지 자동 감지하고 그렇지 않은 경우 new 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>
function stacktrace(){
return (new Error()).stack.split('\n').reverse().slice(0,-2).reverse().join('\n');
}
다음은 최대 성능 (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>" );
})();
IE보다 Firefox에서 스택 추적을 얻는 것이 더 쉽지만 기본적으로 수행하려는 작업은 다음과 같습니다.
"문제가있는"코드를 try / catch 블록으로 감싸십시오.
try {
// some code that doesn't work
var t = null;
var n = t.not_a_value;
}
catch(e) {
}
"error"객체의 내용을 살펴보면 다음 필드가 포함됩니다.
e.fileName : 문제가 발생한 소스 파일 / 페이지 e.lineNumber : 문제가 발생한 파일 / 페이지의 줄 번호 e.message : 발생한 오류 유형을 설명하는 간단한 메시지 e.name : 유형 위의 예에서 발생한 오류는 'TypeError'여야합니다. e.stack : 예외를 발생시킨 스택 추적을 포함합니다.
이것이 도움이되기를 바랍니다.
IE11을 사용하여 smartgwt에서 끝없는 재귀를 조사해야 했으므로 더 깊이 조사하려면 스택 추적이 필요했습니다. 문제는 복제 콘솔이 그렇게 어렵 기 때문에 개발자 콘솔을 사용할 수 없다는 것입니다.
자바 스크립트 메소드에서 다음을 사용하십시오.
try{ null.toString(); } catch(e) { alert(e.stack); }
와우-6 년 동안 한 사람이 보이지 않아서 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)
Firefox를 사용하면 로그에 스택 추적 만 표시되고 Chrome에도 메시지가 표시됩니다. 메시지에 중요한 정보가 포함되어 있다면 이는 놀라운 일이 아닙니다. 항상 둘 다 기록하십시오.
단지 시도
throw new Error('some error here')
이것은 크롬에서 잘 작동합니다.
'development' 카테고리의 다른 글
0으로 끝나는 바이트 배열을 문자열로 변환하는 방법은 무엇입니까? (0) | 2020.02.14 |
---|---|
요소에 JavaScript의 클래스가 포함되어 있는지 확인 하시겠습니까? (0) | 2020.02.14 |
Cassandra의 파티션 키, 복합 키 및 클러스터링 키의 차이점은 무엇입니까? (0) | 2020.02.14 |
Java 인터페이스에서 정적 메소드를 정의 할 수없는 이유는 무엇입니까? (0) | 2020.02.14 |
Git 리포지토리의 리모컨 목록? (0) | 2020.02.14 |