Open rajubngr opened 6 years ago
You could use http://duktape.org/api.html#duk_inspect_callstack_entry to get the programmatic stack trace.
Error objects have a .stack
property which provide a human-readable version. It is backed by a hidden symbol (an internal property) listing the stack trace data in a non-version-compatible internal format.
The error .stack
includes both JS and native call stack entries. In your case there's an initial eval call, which has called an anonymous function, then some function in Main.c, which ultimately has created the stack trace.
If your JS code included other JS calls, they would be visible in .stack
too. For example
duk> function foo() { throw new Error("aiee"); }
= undefined
duk> function bar() { foo(); }
= undefined
duk> function quux() { bar(); }
= undefined
duk> quux();
Error: aiee
at foo (input:1)
at bar (input:1)
at quux (input:1)
at global (input:1) preventsyield
Is there a way to get only Javascript stack trace avoiding native stack ?
To clarify a bit, "native" in this case only means Duktape/C functions called from JavaScript code. Your actual native stack (native-to-native calls) isn't included.
I mean that avoiding/supressing Duktape/C functions stack .
@rajubngr But note that all built-in functions, like Array .forEach(), are Duktape/C functions. Do you really want to hide them from the stack? For example:
((o) Duktape [linenoise] 2.2.99 (v2.2.0-135-g8d5fbe7f)
duk> function bar() { decodeURIComponent('%fg'); }
= undefined
duk> function foo(arr) { arr.forEach(bar); }
= undefined
duk> foo([ 1, 2, 3 ])
URIError: invalid input
at [anon] (duk_bi_global.c:341) internal
at decodeURIComponent () native strict preventsyield
at bar (input:1) preventsyield
at forEach () native strict preventsyield
at foo (input:1)
at global (input:1) preventsyield
Here the call sequence is:
If Duktape/C functions, and the final "synthetic" internal call site were removed, the stack trace would look like:
URIError: invalid input
at bar (input:1) preventsyield
at foo (input:1)
at global (input:1) preventsyield
Is this really what you want, i.e. for the .forEach() and decodeURIComponent() to be hidden?
If you just want to hide the synthetic initial line (duktape.c + line number), but keep functions like .forEach(), you could install a Duktape.errCreate(e) function that would read and replace the .stack
property after pattern matching and removing the line. That would look something like (formatting added):
duk> Duktape.errCreate = function (e) {
var stack = e.stack.replace(/^\s*.*internal\n/m, '');
e.stack = stack;
return e; }
= {_func:true}
duk> foo([ 1, 2, 3 ])
URIError: invalid input
at decodeURIComponent () native strict preventsyield
at bar (input:1) preventsyield
at forEach () native strict preventsyield
at foo (input:1)
at global (input:1) preventsyield
Thanks Svaarala I was looking for the same , I want to hide the synthetic initial line (duktape.c + line number).
My requirement is to get only Javascript information for error object like current line number of JS file , filename of JavaScript, stack of only Javascript functions and files .
If I create error object from Duktape c function , error object should give me filename and lineNumber...etc only of javascript ,like below V8 API .
static Local<StackTrace> v8::StackTrace::CurrentStackTrace()
http://bespin.cz/~ondras/html/classv8_1_1StackTrace.html#a030e8de1b13d720bb2bfac5cb8bc914b.
Is there a way to achieve the same in Duktape ?
Whether error .fileName
and lineNumber
should be for a JS call site or the C call site depends on the use case, see discussion in https://github.com/svaarala/duktape/blob/master/doc/error-objects.rst#choosing-filename-and-linenumber-to-blame-for-an-error. The current rules for choosing the file/line are also described there, with notes for future work to allow e.g. functions to be tagged "infrastructure" so they wouldn't be blamed (Duktape does this for its internal call sites magically).
As things stand now, you can use errCreate() to override the default .fileName
and .lineNumber
with whatever logic you want. You can either use .stack
as the input and pattern match that, or use Duktape.act() or its C equivalent duk_inspect_callstack_entry() to walk the callstack.
when I create error object from duktape c function using below api
duk_push_error_object(ctx, DUK_ERR_TYPE_ERROR, "invalid argument value: %d", 605);
Duktape.errCreate = function(err){... return err}; is not getting called
Can you paste some code? This test case covers using errCreate from C code: https://github.com/svaarala/duktape/blob/master/tests/api/test-errhandler.c.
@rajubngr Any news on this?
@svaarala
duk_push_error_object(ctx, DUK_ERR_TYPE_ERROR, "invalid argument value: %d", 605);
Using the above statement , I'm able to see that below function is getting called
Duktape.errCreate = function(err){... return err};
But my actual requirement is when I push error object from Duktape c function , I need to get the last executed javascript statement code details like lineNumber of the javascript code, fileName of the javascript file and stack of javaScript ..etc in Duktape c function .
Just to be sure, how are you seeing that errCreate is not getting called? Note that if the errCreate() handler throws an error, it will be silently eaten. I'm asking this because the test case linked above does duk_push_error_object() also and covers the errCreate call (specifically in test_4).
But my actual requirement is when I push error object from Duktape c function , I need to get the last executed javascript statement code details like lineNumber of the javascript code, fileName of the javascript file and stack of javaScript ..etc in Duktape c function .
These are available via http://duktape.org/api.html#duk_inspect_callstack_entry only at this point.
Regarding duk_inspect_callstack_entry()
keep in mind that the callstack will include Duktape/C calls so you will need to drill through the entries until you find the first JavaScript one.
_Just to be sure, how are you seeing that errCreate is not getting called? Note that if the errCreate() handler throws an error, it will be silently eaten. I'm asking this because the test case linked above does duk_push_error_object() also and covers the errCreate call (specifically in test4).
Sorry there was mistake due to copy paste that resulted in to mentioning errCreate
is not getting called but actually errCreate
function is getting called when I push error object . As I said my requirement is to get the JavaScript info .... I will try suggested solution of using
duk_inspect_callstack_entry()
I have a requirement to get the current JavaScript execution stack from duktape c file similar to V8 function listed below . http://bespin.cz/~ondras/html/classv8_1_1StackTrace.html#a030e8de1b13d720bb2bfac5cb8bc914b Is there a way to achieve same in Duktape ? I have created error object from duktape environment but that is giving stack of duktape c file but not JS stack . ex: duktape code
duk_idx_t err_idx = duk_push_error_object(ctx, DUK_ERR_TYPE_ERROR, "invalid argument value: %d", 605);
duk_get_prop_string(ctx,-1,"stack");
const char* stack = duk_safe_to_string(ctx,-1);
printf("error object stack = %s \n",stack);
output :##############
error object stack = TypeError: invalid argument value: 605
at [anon] (examples/kony/Main.c:218) internal
at [anon] () native strict preventsyield
at eval (eval:22) preventsyield