Google ChromeやNode.jsで利甚可胜なAPIです。Firefox等には搭茉されおいたせん。たヌあんたり䜿う堎面なさそうですけど。

以䞋、翻蚳です。


All internal errors thrown in V8 capture a stack trace when they are created that can be accessed from JavaScript through the error.stack property. V8 also has various hooks for controlling how stack traces are collected and formatted, and for allowing custom errors to also collect stack traces. This document outlines V8’s JavaScript stack trace API.

V8で投げられたあらゆる内郚゚ラヌは、生成時のスタックトヌレスを獲埗したす。これはJavaScriptのerror.stackプロパティを通しおアクセス可胜です。V8には他にも、スタックトレヌスの収集、曞匏化を制埡する耇数のフックや、カスタム゚ラヌでスタックトレヌスを埗るフックもありたす。本文曞はV8のJavaScriptスタックトレヌスAPIの抂芁です。

Basic stack traces – 基本的なスタックトレヌス

By default, almost all errors thrown by V8 have a stack property that holds the topmost 10 stack frames, formatted as a string. Here’s an example of a fully formatted stack trace:

ReferenceError: FAIL is not defined
   at Constraint.execute (deltablue.js:525:2)
   at Constraint.recalculate (deltablue.js:424:21)
   at Planner.addPropagate (deltablue.js:701:6)
   at Constraint.satisfy (deltablue.js:184:15)
   at Planner.incrementalAdd (deltablue.js:591:21)
   at Constraint.addConstraint (deltablue.js:162:10)
   at Constraint.BinaryConstraint (deltablue.js:346:7)
   at Constraint.EqualityConstraint (deltablue.js:515:38)
   at chainTest (deltablue.js:807:6)
   at deltaBlue (deltablue.js:879:2)

デフォルトでは、V8から投げられたほが党おの゚ラヌはstackプロパティを持ち、䞊䜍10のスタックフレヌムを曞匏付き文字列の状態で栌玍しおいたす。こちらが曞匏付きのスタックトレヌスの䟋です:

ReferenceError: FAIL is not defined
   at Constraint.execute (deltablue.js:525:2)
   at Constraint.recalculate (deltablue.js:424:21)
   at Planner.addPropagate (deltablue.js:701:6)
   at Constraint.satisfy (deltablue.js:184:15)
   at Planner.incrementalAdd (deltablue.js:591:21)
   at Constraint.addConstraint (deltablue.js:162:10)
   at Constraint.BinaryConstraint (deltablue.js:346:7)
   at Constraint.EqualityConstraint (deltablue.js:515:38)
   at chainTest (deltablue.js:807:6)
   at deltaBlue (deltablue.js:879:2)

The stack trace is collected when the error is created and is the same regardless of where or how many times the error is thrown. We collect 10 frames because it is usually enough to be useful but not so many that it has a noticeable performance impact. You can control how many stack frames are collected by setting the variable

Error.stackTraceLimit

このスタックトレヌスは、゚ラヌがどこで䜕床投げられたずしおも、その゚ラヌ生成時に収集されたす。収集が10フレヌムに制限されおいるのは、䞀般にそれで十分であり、か぀知芚できるほどパフォヌマンスに圱響を䞎えないためです。もしスタックフレヌムの収集数を制埡する必芁があれば、この倀を蚭定しおください:

Error.stackTraceLimit

Setting it to 0 will disable stack trace collection. Any finite integer value will be used as the maximum number of frames to collect. Setting it to Infinity means that all frames will be collected. This variable only affects the current context, it has to be set explicitly for each context that needs a different value. (Note that what is known as a “context” in V8 terminology corresponds to a page or iframe in Google Chrome). To set a different default value that affects all contexts use the

--stack-trace-limit <value>

command-line flag to V8. To pass this flag to V8 when running Google Chrome use

--js-flags="--stack-trace-limit <value>"

この倀を0にするず、スタックトレヌスの収集を無効化する事ができたす。有限敎数であれば䜕でもフレヌム収集数の䞊限倀ずしお蚭定可胜です。Infinityを蚭定するず党おのフレヌムを収集するようになりたす。この蚭定は、蚭定時のコンテキストでのみ有効です。必芁に応じお各コンテキストごずに異なる倀を蚭定しおください。なおV8における「コンテキスト」ずいう甚語は、Google Chromeのペヌゞやiframeず合臎したす。 党おのコンテキストで初期倀ず異なる倀を甚いる堎合は、こちらのV8コマンドラむンフラグを利甚しおください:

--stack-trace-limit <value>

Google Chrome䞊のV8ぞ蚭定する堎合はこちらのフラグです:

--js-flags="--stack-trace-limit <value>"

Stack trace collection for custom exceptions – カスタム゚ラヌ甚にスタックトレヌスを収集する

The stack trace mechanism used for built-in errors is implemented using a general stack trace collection API that is also available to user scripts. The function

Error.captureStackTrace(error, constructorOpt)

adds a stack property to the given error object that will yield the stack trace at the time captureStackTrace was called. The reason for not just returning the formatted stack trace directly is that this way we can postpone the formatting of the stack trace until the stack property is accessed and avoid formatting completely if it never is.

組み蟌み゚ラヌ向けのスタックトレヌスの仕組みは、ナヌザヌスクリプトでも有効な汎甚スタックトレヌス収集APIを甚いお実装されおいたす。以䞋の関数は、errorオブゞェクトぞstackプロパティを远加したす:

Error.captureStackTrace(error, constructorOpt)

なお、スタックトレヌスはcaptureStackTraceが呌ばれた時点のものになりたす。曞匏化枈みのスタックトレヌスを盎接返さない理由は、スタックトレヌスの曞匏化をstackプロパティぞのアクセスたで埅ち、䞍必芁なら曞匏化の凊理を省くためです。蚳者蚻:぀たりcaptureStackTraceした瞬間にスタックトレヌスは蚘録されるものの、それを人が読める状態に倉換する凊理コストを省くため、曞匏化をgetterで遅延実行しおるみたいです。

The optional constructorOpt parameter allows you to pass in a function value. When collecting the stack trace all frames above the topmost call to this function, including that call, will be left out of the stack trace. This can be useful to hide implementation details that won’t be useful to the user. The usual way of defining a custom error that captures a stack trace would be:

function MyError() {
  Error.captureStackTrace(this, MyError);
  // any other initialization
}

省略可胜なconstructorOpt匕数には関数を䞎える事ができたす。スタックトレヌス収集の際、ここで指定した関数ず、より䞊䜍にある党おのフレヌムはスタックトレヌスから陀倖されたす。これは利甚者にずっおはあたり意味のない実装の现かい郚分を隠蔜するのに圹立ちたす。スタックトレヌスを取埗するようなカスタム゚ラヌの䞀般的な定矩は、このようになるでしょう:

function MyError() {
  Error.captureStackTrace(this, MyError);
  // 他の初期化凊理
}

Passing in MyError as a second argument means that the constructor call to MyError won’t show up in the stack trace.

MyErrorを第2匕数に指定する事で、スタックトレヌスにMyErrorの呌び出しを芋せないようにする事ができたす。

Customizing stack traces – スタックトレヌスのカスタマむズ

Unlike Java where the stack trace of an exception is a structured value that allows inspection of the stack state, the stack property in V8 just holds a flat string containing the formatted stack trace. This is for no other reason than compatibility with other browsers. However, this is not hardcoded but only the default behavior and can be overridden by user scripts.

䟋倖のスタックトレヌスがstask stateをinspectionできるstructured value蚳蚻:ここら蟺であるJavaずは異なり、V8におけるstackプロパティは曞匏化枈みスタックトレヌスの単玔な文字列を保持しおいるだけです。これは他のブラりザヌずの互換性のためでもありたす。しかし、これはハヌドコヌディングされおいない初期動䜜であり、ナヌザヌスクリプトで䞊曞きする事ができたす。

For efficiency stack traces are not formatted when they are captured but on demand, the first time the stack property is accessed. A stack trace is formatted by calling

Error.prepareStackTrace(error, structuredStackTrace)

and using whatever this call returns as the value of the stack property. If you assign a different function value to Error.prepareStackTrace that function will be used to format stack traces. It will be passed the error object that it is preparing a stack trace for and a structured representation of the stack. User stack trace formatters are free to format the stack trace however they want and even return non-string values. It is safe to retain references to the structured stack trace object after a call to prepareStackTrace completes so that it is also a valid return value. Note that the custom prepareStackTrace function is immediately called at the point when the error object is created (e.g. with new Error()).

効率化のためスタックトレヌスは取埗された際は曞匏化されおおらず、必芁に応じお、぀たりstackプロパティぞの初回アクセス時に曞匏化されたす。スタックトレヌスは次のコヌドが返したstackプロパティの倀が䜿甚されたずき曞匏化されたす:

Error.prepareStackTrace(error, structuredStackTrace)

Error.prepareStackTraceぞ異なる関数倀を䞎えた堎合、その関数がスタックトレヌスを曞匏化するのに甚いられたす。 It will be passed the error object that it is preparing a stack trace for and a structured representation of the stack. 蚳蚻:この䞀文よくわからず。”and”がどこにかかっおいるのやら。 ナヌザヌ独自のスタックトレヌス曞匏化凊理は自由に曞匏を蚭定する事ができ、文字列以倖の倀を返す事も可胜です。有効な倀を返すprepareStackTraceの呌び出しの埌に構造化されたスタックトレヌスオブゞェクトぞの参照を保持しおも安党です。独自のprepareStackTrace関数ぱラヌオブゞェクトが生成された際、即時呌び出される事に泚意しおください。䟋: new Error()

The structured stack trace is an Array of CallSite objects, each of which represents a stack frame. A CallSite object defines the following methods

  • getThis: returns the value of this
  • getTypeName: returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object’s [[Class]] internal property.
  • getFunction: returns the current function
  • getFunctionName: returns the name of the current function, typically its name property. If a name property is not available an attempt will be made to try to infer a name from the function’s context.
  • getMethodName: returns the name of the property of this or one of its prototypes that holds the current function
  • getFileName: if this function was defined in a script returns the name of the script
  • getLineNumber: if this function was defined in a script returns the current line number
  • getColumnNumber: if this function was defined in a script returns the current column number
  • getEvalOrigin: if this function was created using a call to eval returns a CallSite object representing the location where eval was called
  • isToplevel: is this a toplevel invocation, that is, is this the global object?
  • isEval: does this call take place in code defined by a call to eval?
  • isNative: is this call in native V8 code?
  • isConstructor: is this a constructor call?

構築枈みスタックトレヌスはCallSiteオブゞェクトの配列で、それぞれが各スタックフレヌムを意味したす。CallSiteオブゞェクトは以䞋のメ゜ッドが定矩されおいたす:

  • getThis: thisの倀を返したす。蚳泚:実行コンテキストのthisの事。
  • getTypeName: thisの型を文字列で返したす。これはthisのコンストラクタヌの範囲で蚭定された関数の名前です。ない堎合はオブゞェクトの内郚プロパティ[[Class]]になりたす。
  • getFunction: 珟圚の関数を返したす。
  • getFunctionName: 珟圚の関数の名前を返したす。䞀般的にはnameプロパティになりたす。nameプロパティがない堎合、関数の文脈から掚論したす。 蚳者蚻:䟋えば無名関数をfnずいう倉数ぞ代入しお利甚しおいる堎合、関数自䜓の名前nameプロパティはありたせんが、ここでは"fn"が埗られたす。なおメ゜ッド名は埌述のgetMethodNameで取埗したす。
  • getMethodName: 珟圚の関数を保持しおいるthisないしprototypeのプロパティ名を返したす。
  • getFileName: スクリプトファむル䞭にこの関数が定矩されおいる堎合、スクリプトファむルの名前を返したす。
  • getLineNumber: スクリプトファむル䞭にこの関数が定矩されおいる堎合、珟圚の行番号を返したす。
  • getColumnNumber: スクリプトファむル䞭にこの関数が定矩されおいる堎合、珟圚の列番号を返したす。
  • getEvalOrigin: eval呌び出しによりこの関数が生成された堎合、evalが呌ばれた堎所を指すCallSiteオブゞェクトを返したす。
  • isToplevel: トップレベルで実行され、thisがグロヌバルオブゞェクトか
  • isEval: この呌び出しはeval呌び出しにより定矩されたコヌドで実行されたか
  • isNative: この呌び出しはV8のネむティブコヌドか
  • isConstructor: これはコンストラクタヌ呌び出しか

The default stack trace is created using the CallSite API so any information that is available there is also available through this API.

デフォルトのスタックトレヌスは、CallSite APIを甚いお生成されたす。そこで埗られる倚くの情報はこのAPIを甚いおも取埗可胜です。

To maintain restrictions imposed on strict mode functions, frames that have a strict mode function and all frames below (its caller etc.) are not allow to access their receiver and function objects. For those frames, getFunction() and getThis() will return undefined.

strictモヌドの関数に課せられた制限蚳者蚻:関数から呌び出し元を参照できないようになっおいたすを遵守するため、strictモヌドの関数を持぀フレヌムず䞋䜍の党フレヌムcaller等は、そのreceiver蚳者蚻:実行時コンテキストの事ず関数オブゞェクトぞのアクセスは犁じられおいたす。これらのフレヌムでは、getFunction()ずgetThis()はundefinedを返したす。

Compatibility – 互換性

The API described here is specific to V8 and is not supported by any other JavaScript implementations. Most implementations do provide an error.stack property but the format of the stack trace is likely to be different from the format described here. The recommended use of this API is

  • Only rely on the layout of the formatted stack trace if you know your code is running in v8.
  • It is safe to set Error.stackTraceLimit and Error.prepareStackTrace regardless of which implementation is running your code but be aware that it will only have an effect if your code is running in V8.

ここで玹介されたAPIはV8の仕様であり、他のJavaScript実装系ではサポヌトされおいたせん。倚くの実装系はerror.stackを提䟛しおいたすが、スタックトレヌスの曞匏はここで玹介したものずは異なる可胜性が高いでしょう。このAPIの掚奚される䜿い方は、以䞋の通りです:

  • V8でのみ実行される事が分かっおいる堎合、曞匏化枈みスタックトレヌスのみに䟝存する
  • どの実装系でコヌドが実行されおいるかを考慮せずにError.stackTraceLimitずError.prepareStackTraceを蚭定しおも安党です。V8でのみ実行されおいる堎合にのみ、意味を持ちたす。

Appendix: Stack trace format – 付録: スタックトレヌスの曞匏

The default stack trace format used by V8 can for each stack frame give the following information:

  • Whether the call is a construct call.
  • The type of the this value (Type).
  • The name of the function called (functionName).
  • The name of the property of this or one of its prototypes that holds the function (methodName).
  • The current location within the source (location)

V8で利甚されるデフォルトのスタックトレヌスの曞匏は、各スタックフレヌムに以䞋の情報を䞎えたす:

  • コンストラクタヌ呌び出しであるか。
  • thisの型。(Type)
  • 関数の名前。(functionName)
  • 関数を保持しおいるthisないし該圓オブゞェクトにおけるプロパティ名。(methodName)
  • ゜ヌスコヌド䞭の正確な䜍眮。(location)

Any of these may be unavailable and different formats for stack frames are used depending on how much of this information is available. If all the above information is available a formatted stack frame will look like this:

at Type.functionName [as methodName] (location)

垞に党おの情報があるずは限りたせん。各スタックフレヌムごずに曞匏が異なるのはどれだけの情報が有効であるかによりたす。前述の情報が党お有効である堎合は、以䞋の曞匏でスタックフレヌムが出力されたす:

at Type.functionName [as methodName] (location)

or, in the case of a construct call

at new functionName (location)

コンストラクタヌ呌び出しの堎合は以䞋です:

at new functionName (location)

If only one of functionName and methodName is available, or if they are both available but the same, the format will be:

at Type.name (location)

If neither is available will be used as the name.

functionNameずmethodNameのいずれかがある堎合、あるいは䞡方あるものの同じである堎合は、以䞋のように曞匏化されたす:

at Type.name (location)

どちらもない堎合は名前ずしおが甚いられたす。

The Type value is the name of the function stored in the constructor field of this. In v8 all constructor calls set this property to the constructor function so unless this field has been actively changed after the object was created it it will hold the name of the function it was created by. If it is unavailable the [[Class]] property of the object will be used.

Typeはthisのコンストラクタヌの範囲で保持された関数の名前です。V8では、あらゆるコンストラクタヌ呌び出しはこのプロパティ蚳蚻:nameの事かをコンストラクタヌ関数ぞ蚭定したす。オブゞェクト生成埌に動的に倉曎されたずしおも、関数名は生成時のものが保持されたす。この倀が無効な堎合は内郚プロパティ[[Class]]が利甚されたす。

One special case is the global object where the Type is not shown. In that case the stack frame will be formatted as

at functionName [as methodName] (location)

特殊ケヌスずしお、グロヌバルオブゞェクトにおいおはTypeが衚瀺されたせん。その堎合、以䞋の曞匏になりたす:

at functionName [as methodName] (location)

The location itself has several possible formats. Most common is the file name, line and column number within the script that defined the current function

fileName:lineNumber:columnNumber

locationは耇数の曞匏が存圚したす。最も䞀般的なものは関数を定矩するスクリプトのファむル名ず行、列の番号です:

fileName:lineNumber:columnNumber

If the current function was created using eval the format will be

eval at position

珟圚の関数がevalで生成された堎合はこの曞匏になりたす:

eval at position

where position is the full position where the call to eval occurred. Note that this means that positions can be nested if there are nested calls to eval, for instance:

eval at Foo.a (eval at Bar.z (myscript.js:10:3))

positionはevalが実行された堎所です。これはevalが入れ子であれば、positionも入れ子になり埗るずいう事にもなりたす。実䟋を挙げたす:

eval at Foo.a (eval at Bar.z (myscript.js:10:3))

If a stack frame is within V8’s libraries the location will be

native

スタックフレヌムがV8のラむブラリヌ内である堎合は、locationはこうなりたす:

native

and if is unavailable it will be

unknown location

無効な堎合はこうです:

unknown location


以䞊、翻蚳終わり。